@awesomeness-js/server 1.1.9 → 1.1.11
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/build/build.js +4 -1
- package/build/postBuild.js +4 -1
- package/index.js +6 -4
- package/package.json +1 -1
- package/src/componentAndPageMemory.js +269 -0
- package/src/componentDependencies.js +9 -19
- package/src/extractUiComponentRefs.js +55 -0
- package/src/fetchPage.js +103 -4
- package/src/resolveRealCasePath.js +0 -4
- package/tests/componentAndPageMemory.test.js +171 -0
- package/tests/fetchPage.test.js +257 -0
- package/tests/fixtures/site-and-components/components/card/index.js +88 -0
- package/tests/fixtures/site-and-components/components/cardMain/index.js +86 -0
- package/tests/fixtures/site-and-components/components/cardMount/index.js +86 -0
- package/tests/fixtures/site-and-components/components/pageInit/index.js +86 -0
- package/tests/fixtures/site-and-components/components/pageScript/index.js +86 -0
- package/tests/fixtures/site-and-components/components/pageWidget/index.js +86 -0
- package/tests/fixtures/site-and-components/sites/site-a/pages/home/init.js +78 -0
- package/tests/fixtures/site-and-components/sites/site-a/pages/home/js/index.js +60 -0
- package/tests/setup.js +1 -0
- package/tsconfig.json +18 -0
- package/types/errors.d.ts +0 -0
- package/types/index.d.ts +109 -0
- package/types/src/applicationMap.d.ts +1 -0
- package/types/src/awesomenessNormalizeRequest.d.ts +27 -0
- package/types/src/brotliJsonResponse.d.ts +10 -0
- package/types/src/checkAccess.d.ts +5 -0
- package/types/src/componentAndPageMemory.d.ts +75 -0
- package/types/src/componentDependencies.d.ts +6 -0
- package/types/src/config.d.ts +7 -0
- package/types/src/extractUiComponentRefs.d.ts +5 -0
- package/types/src/fetchPage.d.ts +4 -0
- package/types/src/getConfig.d.ts +2 -0
- package/types/src/getMD.d.ts +1 -0
- package/types/src/init.d.ts +2 -0
- package/types/src/koa/attachAwesomenessRequest.d.ts +1 -0
- package/types/src/koa/cors.d.ts +1 -0
- package/types/src/koa/errorHandler.d.ts +1 -0
- package/types/src/koa/finalFormat.d.ts +1 -0
- package/types/src/koa/jsonBodyParser.d.ts +1 -0
- package/types/src/koa/routeRequest.d.ts +1 -0
- package/types/src/koa/serverUp.d.ts +1 -0
- package/types/src/koa/staticFiles.d.ts +1 -0
- package/types/src/koa/timeout.d.ts +1 -0
- package/types/src/pageInfo.d.ts +8 -0
- package/types/src/reRoute.d.ts +7 -0
- package/types/src/resolveRealCasePath.d.ts +1 -0
- package/types/src/specialPaths.d.ts +3 -0
- package/types/src/start.d.ts +1 -0
- package/types/src/validateRequest.d.ts +2 -0
- package/types/src/ws/handlers.d.ts +4 -0
- package/types/src/ws/index.d.ts +1 -0
package/build/build.js
CHANGED
package/build/postBuild.js
CHANGED
package/index.js
CHANGED
|
@@ -7,8 +7,10 @@ import _applicationMap from './src/applicationMap.js';
|
|
|
7
7
|
import _awesomenessNormalizeRequest from './src/awesomenessNormalizeRequest.js';
|
|
8
8
|
import _brotliJsonResponse from './src/brotliJsonResponse.js';
|
|
9
9
|
import _checkAccess from './src/checkAccess.js';
|
|
10
|
+
import _componentAndPageMemory from './src/componentAndPageMemory.js';
|
|
10
11
|
import _componentDependencies from './src/componentDependencies.js';
|
|
11
12
|
import _config from './src/config.js';
|
|
13
|
+
import _extractUiComponentRefs from './src/extractUiComponentRefs.js';
|
|
12
14
|
import _fetchPage from './src/fetchPage.js';
|
|
13
15
|
import _getConfig from './src/getConfig.js';
|
|
14
16
|
import _getMD from './src/getMD.js';
|
|
@@ -35,8 +37,10 @@ export { _applicationMap as applicationMap };
|
|
|
35
37
|
export { _awesomenessNormalizeRequest as awesomenessNormalizeRequest };
|
|
36
38
|
export { _brotliJsonResponse as brotliJsonResponse };
|
|
37
39
|
export { _checkAccess as checkAccess };
|
|
40
|
+
export { _componentAndPageMemory as componentAndPageMemory };
|
|
38
41
|
export { _componentDependencies as componentDependencies };
|
|
39
42
|
export { _config as config };
|
|
43
|
+
export { _extractUiComponentRefs as extractUiComponentRefs };
|
|
40
44
|
export { _fetchPage as fetchPage };
|
|
41
45
|
export { _getConfig as getConfig };
|
|
42
46
|
export { _getMD as getMD };
|
|
@@ -71,18 +75,16 @@ export default {
|
|
|
71
75
|
awesomenessNormalizeRequest: _awesomenessNormalizeRequest,
|
|
72
76
|
brotliJsonResponse: _brotliJsonResponse,
|
|
73
77
|
checkAccess: _checkAccess,
|
|
78
|
+
componentAndPageMemory: _componentAndPageMemory,
|
|
74
79
|
componentDependencies: _componentDependencies,
|
|
75
80
|
config: _config,
|
|
81
|
+
extractUiComponentRefs: _extractUiComponentRefs,
|
|
76
82
|
fetchPage: _fetchPage,
|
|
77
83
|
getConfig: _getConfig,
|
|
78
84
|
getMD: _getMD,
|
|
79
85
|
init: _init,
|
|
80
86
|
pageInfo: _pageInfo,
|
|
81
87
|
reRoute: _reRoute,
|
|
82
|
-
/**
|
|
83
|
-
* Case-insensitive real path resolver.
|
|
84
|
-
* Works correctly on Windows, macOS, and Linux/Docker.
|
|
85
|
-
*/
|
|
86
88
|
resolveRealCasePath: _resolveRealCasePath,
|
|
87
89
|
specialPaths: _specialPaths,
|
|
88
90
|
start: _start,
|
package/package.json
CHANGED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { createHash } from "crypto";
|
|
2
|
+
import { readFileSync, statSync } from "fs";
|
|
3
|
+
import extractUiComponentRefs from "./extractUiComponentRefs.js";
|
|
4
|
+
|
|
5
|
+
const FILE_CACHE_LIMIT = 2000;
|
|
6
|
+
const REFS_CACHE_LIMIT = 5000;
|
|
7
|
+
|
|
8
|
+
const fileCache = new Map();
|
|
9
|
+
const refsCache = new Map();
|
|
10
|
+
|
|
11
|
+
function toMB(bytes) {
|
|
12
|
+
|
|
13
|
+
return Number((bytes / (1024 * 1024)).toFixed(6));
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function toGB(bytes) {
|
|
18
|
+
|
|
19
|
+
return Number((bytes / (1024 * 1024 * 1024)).toFixed(6));
|
|
20
|
+
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function withMBGB(bytes) {
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
bytes,
|
|
27
|
+
mb: toMB(bytes),
|
|
28
|
+
gb: toGB(bytes),
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function pruneCache(cache, limit) {
|
|
34
|
+
|
|
35
|
+
if (cache.size <= limit) {
|
|
36
|
+
|
|
37
|
+
return;
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const deleteCount = cache.size - limit;
|
|
42
|
+
let i = 0;
|
|
43
|
+
|
|
44
|
+
for (const key of cache.keys()) {
|
|
45
|
+
|
|
46
|
+
cache.delete(key);
|
|
47
|
+
i += 1;
|
|
48
|
+
|
|
49
|
+
if (i >= deleteCount) {
|
|
50
|
+
|
|
51
|
+
break;
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function hashContent(content) {
|
|
60
|
+
|
|
61
|
+
return createHash("sha1").update(content).digest("hex");
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function refsCacheKey(content, options) {
|
|
66
|
+
|
|
67
|
+
const {
|
|
68
|
+
namespace = "ui",
|
|
69
|
+
includeCall = true,
|
|
70
|
+
includeDotAccess = false,
|
|
71
|
+
cacheContext = "",
|
|
72
|
+
} = options || {};
|
|
73
|
+
const contentHash = hashContent(content);
|
|
74
|
+
const contextPart = cacheContext ? `${cacheContext}|` : "";
|
|
75
|
+
|
|
76
|
+
return `${contextPart}${namespace}|${includeCall}|${includeDotAccess}|${contentHash}`;
|
|
77
|
+
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function refsCacheKeyFromFile(filePath, fileMeta, options = {}) {
|
|
81
|
+
|
|
82
|
+
const {
|
|
83
|
+
namespace = "ui",
|
|
84
|
+
includeCall = true,
|
|
85
|
+
includeDotAccess = false,
|
|
86
|
+
cacheContext = `file:${filePath}`,
|
|
87
|
+
} = options || {};
|
|
88
|
+
const contextPart = cacheContext ? `${cacheContext}|` : "";
|
|
89
|
+
|
|
90
|
+
return `${contextPart}${namespace}|${includeCall}|${includeDotAccess}|mtime:${fileMeta.mtimeMs}|size:${fileMeta.size}`;
|
|
91
|
+
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function getFileCacheEntry(filePath) {
|
|
95
|
+
|
|
96
|
+
const stat = statSync(filePath);
|
|
97
|
+
const cacheEntry = fileCache.get(filePath);
|
|
98
|
+
|
|
99
|
+
if (
|
|
100
|
+
cacheEntry &&
|
|
101
|
+
cacheEntry.mtimeMs === stat.mtimeMs &&
|
|
102
|
+
cacheEntry.size === stat.size
|
|
103
|
+
) {
|
|
104
|
+
|
|
105
|
+
return cacheEntry;
|
|
106
|
+
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const content = readFileSync(filePath, "utf-8");
|
|
110
|
+
const nextEntry = {
|
|
111
|
+
mtimeMs: stat.mtimeMs,
|
|
112
|
+
size: stat.size,
|
|
113
|
+
content,
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
fileCache.set(filePath, nextEntry);
|
|
117
|
+
pruneCache(fileCache, FILE_CACHE_LIMIT);
|
|
118
|
+
|
|
119
|
+
return nextEntry;
|
|
120
|
+
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function readFileMemoized(filePath) {
|
|
124
|
+
|
|
125
|
+
return getFileCacheEntry(filePath).content;
|
|
126
|
+
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function extractUiRefsMemoized(content, options = {}) {
|
|
130
|
+
|
|
131
|
+
if (typeof content !== "string" || !content.length) {
|
|
132
|
+
|
|
133
|
+
return [];
|
|
134
|
+
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const key = refsCacheKey(content, options);
|
|
138
|
+
const existing = refsCache.get(key);
|
|
139
|
+
|
|
140
|
+
if (existing) {
|
|
141
|
+
|
|
142
|
+
return existing;
|
|
143
|
+
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const refs = extractUiComponentRefs(content, options);
|
|
147
|
+
|
|
148
|
+
refsCache.set(key, refs);
|
|
149
|
+
pruneCache(refsCache, REFS_CACHE_LIMIT);
|
|
150
|
+
|
|
151
|
+
return refs;
|
|
152
|
+
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function extractUiRefsFromFileMemoized(filePath, options = {}) {
|
|
156
|
+
|
|
157
|
+
const fileEntry = getFileCacheEntry(filePath);
|
|
158
|
+
const extractionOptions = options.cacheContext
|
|
159
|
+
? options
|
|
160
|
+
: {
|
|
161
|
+
...options,
|
|
162
|
+
cacheContext: `file:${filePath}`,
|
|
163
|
+
};
|
|
164
|
+
const key = refsCacheKeyFromFile(filePath, fileEntry, extractionOptions);
|
|
165
|
+
const existing = refsCache.get(key);
|
|
166
|
+
|
|
167
|
+
if (existing) {
|
|
168
|
+
|
|
169
|
+
return existing;
|
|
170
|
+
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const refs = extractUiComponentRefs(fileEntry.content, extractionOptions);
|
|
174
|
+
|
|
175
|
+
refsCache.set(key, refs);
|
|
176
|
+
pruneCache(refsCache, REFS_CACHE_LIMIT);
|
|
177
|
+
|
|
178
|
+
return refs;
|
|
179
|
+
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function clearComponentAndPageMemory() {
|
|
183
|
+
|
|
184
|
+
fileCache.clear();
|
|
185
|
+
refsCache.clear();
|
|
186
|
+
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function getComponentAndPageMemoryStatus({
|
|
190
|
+
includeKeys = true,
|
|
191
|
+
sampleSize = 25,
|
|
192
|
+
} = {}) {
|
|
193
|
+
|
|
194
|
+
let fileCacheBytes = 0;
|
|
195
|
+
|
|
196
|
+
for (const value of fileCache.values()) {
|
|
197
|
+
|
|
198
|
+
fileCacheBytes += Buffer.byteLength(value.content || "", "utf-8");
|
|
199
|
+
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
let refsCacheBytes = 0;
|
|
203
|
+
|
|
204
|
+
for (const [ key, value ] of refsCache.entries()) {
|
|
205
|
+
|
|
206
|
+
refsCacheBytes += Buffer.byteLength(key, "utf-8");
|
|
207
|
+
refsCacheBytes += Buffer.byteLength(JSON.stringify(value || []), "utf-8");
|
|
208
|
+
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const processMemoryUsage = typeof process?.memoryUsage === "function"
|
|
212
|
+
? process.memoryUsage()
|
|
213
|
+
: null;
|
|
214
|
+
const totalCacheBytes = fileCacheBytes + refsCacheBytes;
|
|
215
|
+
const processMemoryUsageWithUnits = processMemoryUsage
|
|
216
|
+
? {
|
|
217
|
+
rss: withMBGB(processMemoryUsage.rss || 0),
|
|
218
|
+
heapTotal: withMBGB(processMemoryUsage.heapTotal || 0),
|
|
219
|
+
heapUsed: withMBGB(processMemoryUsage.heapUsed || 0),
|
|
220
|
+
external: withMBGB(processMemoryUsage.external || 0),
|
|
221
|
+
arrayBuffers: withMBGB(processMemoryUsage.arrayBuffers || 0),
|
|
222
|
+
}
|
|
223
|
+
: null;
|
|
224
|
+
|
|
225
|
+
const out = {
|
|
226
|
+
limits: {
|
|
227
|
+
fileCacheLimit: FILE_CACHE_LIMIT,
|
|
228
|
+
refsCacheLimit: REFS_CACHE_LIMIT,
|
|
229
|
+
},
|
|
230
|
+
counts: {
|
|
231
|
+
fileCacheEntries: fileCache.size,
|
|
232
|
+
refsCacheEntries: refsCache.size,
|
|
233
|
+
},
|
|
234
|
+
approximateBytes: {
|
|
235
|
+
fileCacheBytes,
|
|
236
|
+
refsCacheBytes,
|
|
237
|
+
totalCacheBytes,
|
|
238
|
+
},
|
|
239
|
+
approximateMemory: {
|
|
240
|
+
fileCache: withMBGB(fileCacheBytes),
|
|
241
|
+
refsCache: withMBGB(refsCacheBytes),
|
|
242
|
+
totalCache: withMBGB(totalCacheBytes),
|
|
243
|
+
},
|
|
244
|
+
processMemoryUsage,
|
|
245
|
+
processMemoryUsageWithUnits,
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
if (includeKeys) {
|
|
249
|
+
|
|
250
|
+
out.keys = {
|
|
251
|
+
fileCacheKeys: [ ...fileCache.keys() ].slice(0, sampleSize),
|
|
252
|
+
refsCacheKeys: [ ...refsCache.keys() ].slice(0, sampleSize),
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return out;
|
|
258
|
+
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const componentAndPageMemory = {
|
|
262
|
+
readFileMemoized,
|
|
263
|
+
extractUiRefsMemoized,
|
|
264
|
+
extractUiRefsFromFileMemoized,
|
|
265
|
+
clearComponentAndPageMemory,
|
|
266
|
+
getComponentAndPageMemoryStatus,
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
export default componentAndPageMemory;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import { fileURLToPath } from "url";
|
|
3
3
|
import { each, getAllFiles } from "@awesomeness-js/utils";
|
|
4
|
-
import { readFileSync } from "fs";
|
|
5
4
|
import getConfig from "./getConfig.js";
|
|
5
|
+
import {
|
|
6
|
+
extractUiRefsFromFileMemoized,
|
|
7
|
+
readFileMemoized,
|
|
8
|
+
} from "./componentAndPageMemory.js";
|
|
6
9
|
|
|
7
10
|
function urlToFsPath(u) {
|
|
8
11
|
|
|
@@ -34,22 +37,6 @@ function urlToFsPath(u) {
|
|
|
34
37
|
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
function extractUiFirstParts(str) {
|
|
38
|
-
|
|
39
|
-
const regex = /ui\.([a-zA-Z0-9_]+)(?:\.[a-zA-Z0-9_.]*)?\(/g;
|
|
40
|
-
const matches = new Set();
|
|
41
|
-
let match;
|
|
42
|
-
|
|
43
|
-
while ((match = regex.exec(str)) !== null) {
|
|
44
|
-
|
|
45
|
-
matches.add(match[1]);
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return [ ...matches ];
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
40
|
export default function componentDependencies(
|
|
54
41
|
allComponents,
|
|
55
42
|
{
|
|
@@ -186,14 +173,17 @@ export default function componentDependencies(
|
|
|
186
173
|
|
|
187
174
|
// readFileSync must use chosenRoot + relative file path
|
|
188
175
|
const filePath = path.isAbsolute(file) ? file : path.join(chosenRoot, file);
|
|
189
|
-
const fileContent =
|
|
176
|
+
const fileContent = readFileMemoized(filePath);
|
|
190
177
|
|
|
191
178
|
const lines = fileContent.split("\n");
|
|
192
179
|
let fileWithImportsStripped = "";
|
|
193
180
|
|
|
194
181
|
try {
|
|
195
182
|
|
|
196
|
-
const newTest =
|
|
183
|
+
const newTest = extractUiRefsFromFileMemoized(filePath, {
|
|
184
|
+
namespace,
|
|
185
|
+
cacheContext: `component:${component}|file:${filePath}`,
|
|
186
|
+
});
|
|
197
187
|
|
|
198
188
|
if (newTest.length > 0) {
|
|
199
189
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
function escapeRegex(input) {
|
|
2
|
+
|
|
3
|
+
return String(input).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4
|
+
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export default function extractUiComponentRefs(
|
|
8
|
+
str,
|
|
9
|
+
{
|
|
10
|
+
namespace = "ui",
|
|
11
|
+
includeCall = true,
|
|
12
|
+
includeDotAccess = false,
|
|
13
|
+
} = {}
|
|
14
|
+
) {
|
|
15
|
+
|
|
16
|
+
if (typeof str !== "string" || !str.length) {
|
|
17
|
+
|
|
18
|
+
return [];
|
|
19
|
+
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const ns = escapeRegex(namespace);
|
|
23
|
+
const lookaheads = [];
|
|
24
|
+
|
|
25
|
+
if (includeDotAccess) {
|
|
26
|
+
|
|
27
|
+
lookaheads.push("\\.");
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (includeCall) {
|
|
32
|
+
|
|
33
|
+
lookaheads.push("\\(");
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!lookaheads.length) {
|
|
38
|
+
|
|
39
|
+
return [];
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const regex = new RegExp(`${ns}\\.([a-zA-Z0-9_]+)(?=${lookaheads.join("|")})`, "g");
|
|
44
|
+
const matches = new Set();
|
|
45
|
+
let match;
|
|
46
|
+
|
|
47
|
+
while ((match = regex.exec(str)) !== null) {
|
|
48
|
+
|
|
49
|
+
matches.add(match[1]);
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return [ ...matches ];
|
|
54
|
+
|
|
55
|
+
}
|
package/src/fetchPage.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import { fileURLToPath } from "url";
|
|
3
|
+
import { existsSync } from "fs";
|
|
3
4
|
|
|
4
5
|
import componentDependencies from "./componentDependencies.js";
|
|
5
6
|
import pageInfo from "./pageInfo.js";
|
|
6
7
|
import { each, md5, combineFiles } from "@awesomeness-js/utils";
|
|
7
8
|
import getConfig from "./getConfig.js";
|
|
9
|
+
import { extractUiRefsFromFileMemoized, extractUiRefsMemoized } from "./componentAndPageMemory.js";
|
|
8
10
|
|
|
9
11
|
const componentNamespace = "ui";
|
|
10
12
|
const pageNamespaceBase = `app.pages`;
|
|
@@ -51,6 +53,80 @@ export default async function fetchPage(
|
|
|
51
53
|
return pageFnName;
|
|
52
54
|
|
|
53
55
|
}
|
|
56
|
+
|
|
57
|
+
function pageNamespaceInit(pageFnName) {
|
|
58
|
+
|
|
59
|
+
const parts = pageFnName.split(".");
|
|
60
|
+
const inits = [];
|
|
61
|
+
|
|
62
|
+
for (let i = 2; i < parts.length - 1; i++) {
|
|
63
|
+
|
|
64
|
+
inits.push(
|
|
65
|
+
`${parts.slice(0, i + 1).join(".")} = ${parts.slice(0, i + 1).join(".")} || {};`
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return inits.join("\n");
|
|
71
|
+
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function collectComponentsFromPageFiles() {
|
|
75
|
+
|
|
76
|
+
const found = new Set();
|
|
77
|
+
const initPath = path.join(path.dirname(jsPath), "init.js");
|
|
78
|
+
const cacheScope = `site:${awesomenessRequest.site}|page:${page}`;
|
|
79
|
+
|
|
80
|
+
if (existsSync(initPath)) {
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
extractUiRefsFromFileMemoized(initPath, {
|
|
86
|
+
namespace: componentNamespace,
|
|
87
|
+
includeDotAccess: true,
|
|
88
|
+
}).forEach((name) => found.add(name));
|
|
89
|
+
|
|
90
|
+
} catch (err) {
|
|
91
|
+
|
|
92
|
+
console.log("failed to infer components from page init.js", {
|
|
93
|
+
page,
|
|
94
|
+
initPath,
|
|
95
|
+
err,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
|
|
104
|
+
combineFiles(jsPath, "js", {
|
|
105
|
+
processContent: ({ content }) => {
|
|
106
|
+
|
|
107
|
+
extractUiRefsMemoized(content, {
|
|
108
|
+
namespace: componentNamespace,
|
|
109
|
+
includeDotAccess: true,
|
|
110
|
+
cacheContext: `${cacheScope}|js-content`,
|
|
111
|
+
}).forEach((name) => found.add(name));
|
|
112
|
+
|
|
113
|
+
return content;
|
|
114
|
+
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
} catch (err) {
|
|
119
|
+
|
|
120
|
+
console.log("failed to infer components from page js", {
|
|
121
|
+
page,
|
|
122
|
+
err,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return [ ...found ];
|
|
128
|
+
|
|
129
|
+
}
|
|
54
130
|
|
|
55
131
|
|
|
56
132
|
// initialize if not already available
|
|
@@ -156,6 +232,7 @@ export default async function fetchPage(
|
|
|
156
232
|
}) => {
|
|
157
233
|
|
|
158
234
|
const fnName = pageFn(path, awesomenessRequest);
|
|
235
|
+
const namespaceInit = pageNamespaceInit(fnName);
|
|
159
236
|
|
|
160
237
|
content = content.replaceAll(`import ui from '#ui';`, "");
|
|
161
238
|
content = content.replaceAll(`import ui from "#ui";`, "");
|
|
@@ -165,7 +242,14 @@ export default async function fetchPage(
|
|
|
165
242
|
content = content.replaceAll("export default async", `${fnName} = async`);
|
|
166
243
|
content = content.replaceAll("export default", `${fnName} =`);
|
|
167
244
|
|
|
168
|
-
|
|
245
|
+
if (namespaceInit) {
|
|
246
|
+
|
|
247
|
+
content = `${namespaceInit}\n${content}`;
|
|
248
|
+
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return content;
|
|
252
|
+
|
|
169
253
|
|
|
170
254
|
},
|
|
171
255
|
});
|
|
@@ -194,9 +278,24 @@ export default async function fetchPage(
|
|
|
194
278
|
|
|
195
279
|
}
|
|
196
280
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
281
|
+
const explicitComponents = Array.isArray(about?.components) ? about.components : [];
|
|
282
|
+
const inferredComponents = [
|
|
283
|
+
...new Set([
|
|
284
|
+
...collectComponentsFromPageFiles(),
|
|
285
|
+
...(meta.pages[page]?.js
|
|
286
|
+
? extractUiRefsMemoized(meta.pages[page].js, {
|
|
287
|
+
namespace: componentNamespace,
|
|
288
|
+
includeDotAccess: true,
|
|
289
|
+
cacheContext: `site:${awesomenessRequest.site}|page:${page}|bundled-js`,
|
|
290
|
+
})
|
|
291
|
+
: []),
|
|
292
|
+
]),
|
|
293
|
+
];
|
|
294
|
+
const pageComponents = [ ...new Set([ ...explicitComponents, ...inferredComponents ]) ];
|
|
295
|
+
|
|
296
|
+
if (pageComponents.length) {
|
|
297
|
+
|
|
298
|
+
const allDependencies = componentDependencies(pageComponents, {
|
|
200
299
|
componentLocations: awesomenessConfig.componentLocations(awesomenessRequest),
|
|
201
300
|
namespace: componentNamespace,
|
|
202
301
|
showDetails,
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { readdirSync } from "fs";
|
|
2
2
|
import path from "path";
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Case-insensitive real path resolver.
|
|
6
|
-
* Works correctly on Windows, macOS, and Linux/Docker.
|
|
7
|
-
*/
|
|
8
4
|
export default function resolveRealCasePath(inputPath, returnAbsolute = false) {
|
|
9
5
|
|
|
10
6
|
if (!inputPath) return null;
|