@lwrjs/static 0.13.0-alpha.2 → 0.13.0-alpha.21
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/cjs/{utils/static-utils.cjs → index.cjs} +2 -19
- package/build/cjs/providers/static-bundle-provider.cjs +34 -29
- package/build/cjs/providers/static-module-provider.cjs +32 -13
- package/build/cjs/providers/static-resource-provider.cjs +13 -18
- package/build/cjs/site-metadata.cjs +65 -1
- package/build/cjs/tools/dedupe-bundles.cjs +108 -0
- package/build/cjs/utils/decision-tree.cjs +201 -0
- package/build/es/index.d.ts +2 -0
- package/build/es/index.js +2 -0
- package/build/es/providers/static-bundle-provider.d.ts +8 -4
- package/build/es/providers/static-bundle-provider.js +40 -31
- package/build/es/providers/static-module-provider.d.ts +4 -2
- package/build/es/providers/static-module-provider.js +32 -13
- package/build/es/providers/static-resource-provider.d.ts +3 -4
- package/build/es/providers/static-resource-provider.js +20 -26
- package/build/es/site-metadata.d.ts +48 -1
- package/build/es/site-metadata.js +101 -0
- package/build/es/tools/dedupe-bundles.d.ts +3 -0
- package/build/es/tools/dedupe-bundles.js +89 -0
- package/build/es/utils/decision-tree.d.ts +29 -0
- package/build/es/utils/decision-tree.js +267 -0
- package/package.json +9 -5
- package/build/es/utils/static-utils.d.ts +0 -12
- package/build/es/utils/static-utils.js +0 -23
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __markAsModule = (target) => __defProp(target, "__esModule", {value: true});
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, {get: all[name], enumerable: true});
|
|
11
|
+
};
|
|
12
|
+
var __exportStar = (target, module2, desc) => {
|
|
13
|
+
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(module2))
|
|
15
|
+
if (!__hasOwnProp.call(target, key) && key !== "default")
|
|
16
|
+
__defProp(target, key, {get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable});
|
|
17
|
+
}
|
|
18
|
+
return target;
|
|
19
|
+
};
|
|
20
|
+
var __toModule = (module2) => {
|
|
21
|
+
return __exportStar(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? {get: () => module2.default, enumerable: true} : {value: module2, enumerable: true})), module2);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// packages/@lwrjs/static/src/utils/decision-tree.ts
|
|
25
|
+
__markAsModule(exports);
|
|
26
|
+
__export(exports, {
|
|
27
|
+
createFallbackMap: () => createFallbackMap,
|
|
28
|
+
default: () => decision_tree_default
|
|
29
|
+
});
|
|
30
|
+
var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
|
|
31
|
+
var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
|
|
32
|
+
var import_site_metadata = __toModule(require("../site-metadata.cjs"));
|
|
33
|
+
var CHOICE_WILDCARD = "*";
|
|
34
|
+
var CHOICE_EMPTY = "";
|
|
35
|
+
var CHOICE_PROD = "prod";
|
|
36
|
+
var CHOICE_DEBUG = "debug";
|
|
37
|
+
var DecisionTreeImpl = class {
|
|
38
|
+
constructor() {
|
|
39
|
+
this.root = new TreeNode();
|
|
40
|
+
}
|
|
41
|
+
insert(siteArtifactId, artifact, debug, localeFallbacks) {
|
|
42
|
+
const decisionPath = this.createPossibleArtifactChoices({
|
|
43
|
+
id: siteArtifactId,
|
|
44
|
+
localeFallbacks,
|
|
45
|
+
debug
|
|
46
|
+
});
|
|
47
|
+
const choices = decisionPath[0];
|
|
48
|
+
const isLeaf = decisionPath.length == 1;
|
|
49
|
+
for (const [index, key] of choices.entries()) {
|
|
50
|
+
const rank = [index];
|
|
51
|
+
if (!this.root.getChild(key, false)) {
|
|
52
|
+
this.root.addChild(key, new TreeNode(key, ""));
|
|
53
|
+
}
|
|
54
|
+
const nextNode = this.root.getChild(key, false);
|
|
55
|
+
if (isLeaf) {
|
|
56
|
+
nextNode.setArtifact(artifact, rank);
|
|
57
|
+
} else {
|
|
58
|
+
this.deepInsert(1, decisionPath, key, nextNode, artifact, rank);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
deepInsert(level, decisionPath, currentPath, currentNode, artifact, rank) {
|
|
63
|
+
if (level >= decisionPath.length)
|
|
64
|
+
return;
|
|
65
|
+
const choices = decisionPath[level];
|
|
66
|
+
const isLeaf = level === decisionPath.length - 1;
|
|
67
|
+
for (const [index, key] of choices.entries()) {
|
|
68
|
+
const nextRank = [...rank, index];
|
|
69
|
+
if (!currentNode.getChild(key, false)) {
|
|
70
|
+
currentNode.addChild(key, new TreeNode(key, currentPath));
|
|
71
|
+
}
|
|
72
|
+
const nextNode = currentNode.getChild(key, false);
|
|
73
|
+
if (isLeaf) {
|
|
74
|
+
nextNode.setArtifact(artifact, nextRank);
|
|
75
|
+
} else {
|
|
76
|
+
this.deepInsert(level + 1, decisionPath, `${currentPath}/${key}`, nextNode, artifact, nextRank);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
find(siteArtifactId, debug, localeId) {
|
|
81
|
+
const parsedArtifactId = (0, import_site_metadata.parseSiteId)(siteArtifactId);
|
|
82
|
+
const decisionPath = this.createArtifactChoices({
|
|
83
|
+
specifier: parsedArtifactId.specifier,
|
|
84
|
+
version: parsedArtifactId.variants[import_shared_utils.VERSION_SIGIL],
|
|
85
|
+
localeId: localeId ?? parsedArtifactId.variants[import_shared_utils.LOCALE_SIGIL],
|
|
86
|
+
debug
|
|
87
|
+
});
|
|
88
|
+
let currentNode = this.root;
|
|
89
|
+
for (const key of decisionPath) {
|
|
90
|
+
const lastPath = currentNode.getPath();
|
|
91
|
+
currentNode = currentNode.getChild(key);
|
|
92
|
+
if (!currentNode) {
|
|
93
|
+
import_diagnostics.logger.debug(`Module ${key} not found at ${lastPath}`);
|
|
94
|
+
return void 0;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (!currentNode.artifact) {
|
|
98
|
+
import_diagnostics.logger.debug(`Artifact not found at ${currentNode.getPath()}`);
|
|
99
|
+
}
|
|
100
|
+
return currentNode.artifact;
|
|
101
|
+
}
|
|
102
|
+
createArtifactChoices({specifier, version, localeId, debug}) {
|
|
103
|
+
const envChoice = debug ? CHOICE_DEBUG : CHOICE_PROD;
|
|
104
|
+
const versionChoice = getVersionChoice(version);
|
|
105
|
+
const uriVersion = (0, import_shared_utils.normalizeVersionToUri)(versionChoice);
|
|
106
|
+
return [specifier, envChoice, uriVersion, localeId || CHOICE_WILDCARD];
|
|
107
|
+
}
|
|
108
|
+
createPossibleArtifactChoices({
|
|
109
|
+
id,
|
|
110
|
+
localeFallbacks,
|
|
111
|
+
debug
|
|
112
|
+
}) {
|
|
113
|
+
const match = (0, import_site_metadata.parseSiteId)(id);
|
|
114
|
+
const specifier = match.specifier;
|
|
115
|
+
if (!specifier) {
|
|
116
|
+
throw new Error(`Unable to parse${debug ? " debug" : ""} static bundle specifier: ${id}`);
|
|
117
|
+
}
|
|
118
|
+
const versionChoice = getVersionChoice(match.variants[import_shared_utils.VERSION_SIGIL]);
|
|
119
|
+
const versions = versionChoice === CHOICE_EMPTY ? [...new Set([CHOICE_EMPTY, CHOICE_WILDCARD])] : [...new Set([versionChoice, CHOICE_EMPTY])];
|
|
120
|
+
const envChoice = debug ? [CHOICE_DEBUG] : [CHOICE_PROD];
|
|
121
|
+
const localeChoice = match.variants[import_shared_utils.LOCALE_SIGIL];
|
|
122
|
+
const localeId = localeChoice && localeFallbacks ? localeFallbacks[localeChoice] : [CHOICE_WILDCARD];
|
|
123
|
+
return [[specifier], envChoice, versions, localeId];
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
var decision_tree_default = DecisionTreeImpl;
|
|
127
|
+
var TreeNode = class {
|
|
128
|
+
constructor(value = "", parentPath = "") {
|
|
129
|
+
this.children = new Map();
|
|
130
|
+
this.artifact = void 0;
|
|
131
|
+
this.decisionValue = value;
|
|
132
|
+
this.parentPath = parentPath;
|
|
133
|
+
}
|
|
134
|
+
addChild(value, node) {
|
|
135
|
+
this.children.set(value, node);
|
|
136
|
+
}
|
|
137
|
+
setArtifact(artifact, rank) {
|
|
138
|
+
if (this.artifact && isLowerOrEqualRank(rank, this.rank)) {
|
|
139
|
+
import_diagnostics.logger.debug({
|
|
140
|
+
label: "DecisionTree",
|
|
141
|
+
message: `Ignored Artifact ${this.getPath()} ${this.rank} <= ${rank}`
|
|
142
|
+
});
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
import_diagnostics.logger.debug({
|
|
146
|
+
label: "DecisionTree",
|
|
147
|
+
message: `Added artifact at ${this.getPath()}`
|
|
148
|
+
});
|
|
149
|
+
this.rank = rank;
|
|
150
|
+
this.artifact = artifact;
|
|
151
|
+
}
|
|
152
|
+
getChild(key, allowWildcard = true) {
|
|
153
|
+
return allowWildcard ? this.children.get(key) || this.children.get(CHOICE_WILDCARD) : this.children.get(key);
|
|
154
|
+
}
|
|
155
|
+
getPath() {
|
|
156
|
+
return this.parentPath ? this.parentPath + "|" + this.decisionValue : this.decisionValue;
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
function isLowerOrEqualRank(contender, existing) {
|
|
160
|
+
if (!existing) {
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
if (existing.length !== contender.length) {
|
|
164
|
+
throw new Error(`Paths must be of the same length ${existing} not found at ${contender}`);
|
|
165
|
+
}
|
|
166
|
+
for (let i = 0; i < existing.length; i++) {
|
|
167
|
+
if (contender[i] > existing[i]) {
|
|
168
|
+
return true;
|
|
169
|
+
} else if (contender[i] < existing[i]) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
function getVersionChoice(version) {
|
|
176
|
+
if (!version || version === import_shared_utils.VERSION_NOT_PROVIDED) {
|
|
177
|
+
return CHOICE_EMPTY;
|
|
178
|
+
}
|
|
179
|
+
return (0, import_shared_utils.normalizeVersionToUri)(version);
|
|
180
|
+
}
|
|
181
|
+
function createFallbackMap(config) {
|
|
182
|
+
const map = {};
|
|
183
|
+
function findFallbacks(localeId, visited = new Set()) {
|
|
184
|
+
if (visited.has(localeId) || localeId === config.defaultLocale) {
|
|
185
|
+
return [];
|
|
186
|
+
}
|
|
187
|
+
visited.add(localeId);
|
|
188
|
+
const locale = config.locales.find((l) => l.id === localeId);
|
|
189
|
+
if (!locale || !locale.fallback) {
|
|
190
|
+
return [localeId];
|
|
191
|
+
}
|
|
192
|
+
return [localeId, ...findFallbacks(locale.fallback, visited)];
|
|
193
|
+
}
|
|
194
|
+
config.locales.forEach((locale) => {
|
|
195
|
+
if (locale.id !== config.defaultLocale) {
|
|
196
|
+
map[locale.id] = [...new Set([...findFallbacks(locale.id)])];
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
map[CHOICE_WILDCARD] = [CHOICE_WILDCARD];
|
|
200
|
+
return map;
|
|
201
|
+
}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import type { AbstractModuleId, BundleDefinition, BundleProvider, ProviderContext, RuntimeEnvironment, RuntimeParams } from '@lwrjs/types';
|
|
1
|
+
import type { AbstractModuleId, BundleDefinition, BundleProvider, ProviderContext, RuntimeEnvironment, RuntimeParams, SiteMetadata } from '@lwrjs/types';
|
|
2
2
|
export default class StaticBundleProvider implements BundleProvider {
|
|
3
3
|
name: string;
|
|
4
|
-
siteBundles: import("@lwrjs/types").SiteBundles;
|
|
5
|
-
debugSiteBundles?: import("@lwrjs/types").SiteBundles | undefined;
|
|
6
4
|
siteRootDir: string;
|
|
7
5
|
bundleConfig: import("@lwrjs/types").BundleConfig;
|
|
8
6
|
i18n: import("@lwrjs/types").I18NConfig;
|
|
7
|
+
siteMetadata: SiteMetadata;
|
|
9
8
|
constructor(_config: {}, context: ProviderContext);
|
|
10
9
|
bundle<BundleIdentifier extends AbstractModuleId, RE extends RuntimeEnvironment>(moduleId: BundleIdentifier, runtimeEnvironment: RE, runtimeParams: RuntimeParams): Promise<BundleDefinition | undefined>;
|
|
10
|
+
private getBundleMetadata;
|
|
11
|
+
/**
|
|
12
|
+
* Takes a key from the site bundle metadata and creates an appropriate runtime BaseModuleReference to use in the LWR runtime.
|
|
13
|
+
*/
|
|
14
|
+
private getModuleReference;
|
|
11
15
|
/**
|
|
12
16
|
* Get the source code for the a static bundle
|
|
13
17
|
* If we are running in a lambda and the mode is debug we will return the prod source code instead of the debug source code
|
|
@@ -17,6 +21,6 @@ export default class StaticBundleProvider implements BundleProvider {
|
|
|
17
21
|
* @param specifier Root specifier for the requested bundle
|
|
18
22
|
* @param localeId Locale id (e.g. en-US) for the current request
|
|
19
23
|
*/
|
|
20
|
-
getCode(bundlePath: string, debug: boolean, specifier: string, localeId: string): Promise<string>;
|
|
24
|
+
getCode(bundlePath: string, debug: boolean, specifier: string, version: string | undefined, localeId: string): Promise<string>;
|
|
21
25
|
}
|
|
22
26
|
//# sourceMappingURL=static-bundle-provider.d.ts.map
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { logger } from '@lwrjs/diagnostics';
|
|
2
|
-
import { explodeSpecifier, getSpecifier } from '@lwrjs/shared-utils';
|
|
2
|
+
import { VERSION_SIGIL, createIntegrityHash, explodeSpecifier, getSpecifier, isLambdaEnv, } from '@lwrjs/shared-utils';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import fs from 'fs-extra';
|
|
5
|
-
import {
|
|
5
|
+
import { getSiteBundleId, parseSiteId, resolveStaticBundleVersion } from '../site-metadata.js';
|
|
6
6
|
export default class StaticBundleProvider {
|
|
7
7
|
constructor(_config, context) {
|
|
8
8
|
this.name = 'static-bundle-provider';
|
|
9
9
|
if (!context.siteMetadata) {
|
|
10
10
|
throw new Error(`[${this.name}] Site metadata was not found`);
|
|
11
11
|
}
|
|
12
|
-
this.
|
|
13
|
-
this.debugSiteBundles = context.siteMetadata.getDebugSiteBundles();
|
|
12
|
+
this.siteMetadata = context.siteMetadata;
|
|
14
13
|
this.siteRootDir = context.siteMetadata.getSiteRootDir();
|
|
15
14
|
this.bundleConfig = context.config.bundleConfig;
|
|
16
15
|
this.i18n = context.config.i18n;
|
|
@@ -19,37 +18,26 @@ export default class StaticBundleProvider {
|
|
|
19
18
|
const { specifier, name, namespace, version } = moduleId;
|
|
20
19
|
const { debug, i18n: { defaultLocale }, } = runtimeEnvironment;
|
|
21
20
|
const localeId = (runtimeParams?.locale || defaultLocale);
|
|
22
|
-
const
|
|
23
|
-
const metadata = await getLocalizedBundle(specifier, siteBundles, localeId, this.i18n);
|
|
21
|
+
const metadata = this.getBundleMetadata(moduleId, localeId, debug);
|
|
24
22
|
if (!metadata) {
|
|
25
23
|
return undefined;
|
|
26
24
|
}
|
|
27
25
|
// Default bundle source path
|
|
28
26
|
const bundlePath = path.join(this.siteRootDir, metadata.path);
|
|
29
27
|
// Get the associated bundle source code
|
|
30
|
-
const code = await this.getCode(bundlePath, debug, specifier, localeId);
|
|
31
|
-
const imports = metadata.imports.map((
|
|
32
|
-
|
|
33
|
-
if (!importModule.version) {
|
|
34
|
-
// Get version from metadata for un-versioned imports
|
|
35
|
-
importModule.version = resolveStaticBundleVersion(this.siteBundles.bundles[specifier]?.version);
|
|
36
|
-
}
|
|
37
|
-
return importModule;
|
|
38
|
-
});
|
|
39
|
-
const dynamicImports = metadata.dynamicImports?.map((specifier) => {
|
|
40
|
-
const dynamicImportModule = explodeSpecifier(specifier);
|
|
41
|
-
if (!dynamicImportModule.version) {
|
|
42
|
-
// Get version from metadata for un-versioned imports
|
|
43
|
-
dynamicImportModule.version = resolveStaticBundleVersion(this.siteBundles.bundles[specifier]?.version);
|
|
44
|
-
}
|
|
45
|
-
return dynamicImportModule;
|
|
46
|
-
});
|
|
28
|
+
const code = await this.getCode(bundlePath, debug, specifier, version, localeId);
|
|
29
|
+
const imports = metadata.imports.map((importSpecifier) => this.getModuleReference(importSpecifier, localeId, debug));
|
|
30
|
+
const dynamicImports = metadata.dynamicImports?.map((importSpecifier) => this.getModuleReference(importSpecifier, localeId, debug));
|
|
47
31
|
const id = getSpecifier(moduleId);
|
|
48
32
|
const exploded = explodeSpecifier(id);
|
|
49
33
|
// Seem unlikely name was not in the moduleId but just incase set it form the exploded id
|
|
50
|
-
const resolvedName = name
|
|
51
|
-
const resolvedNamespace = namespace
|
|
34
|
+
const resolvedName = name ?? exploded.name;
|
|
35
|
+
const resolvedNamespace = namespace ?? exploded.namespace;
|
|
52
36
|
const resolvedVersion = resolveStaticBundleVersion(metadata.version, version);
|
|
37
|
+
const includedModules = metadata.includedModules?.map((includedId) => {
|
|
38
|
+
const includedModule = this.getModuleReference(includedId, localeId, debug);
|
|
39
|
+
return getSpecifier(includedModule);
|
|
40
|
+
}) || [];
|
|
53
41
|
return {
|
|
54
42
|
code,
|
|
55
43
|
id: getSpecifier({
|
|
@@ -63,15 +51,37 @@ export default class StaticBundleProvider {
|
|
|
63
51
|
version: resolvedVersion,
|
|
64
52
|
specifier: specifier,
|
|
65
53
|
config: this.bundleConfig,
|
|
54
|
+
integrity: metadata.integrity ?? createIntegrityHash(code),
|
|
66
55
|
bundleRecord: {
|
|
67
56
|
// TODO we need to solve include modules for fingerprints support
|
|
68
|
-
includedModules
|
|
57
|
+
includedModules,
|
|
69
58
|
imports,
|
|
70
59
|
dynamicImports,
|
|
71
60
|
},
|
|
72
61
|
src: bundlePath,
|
|
73
62
|
};
|
|
74
63
|
}
|
|
64
|
+
getBundleMetadata(moduleId, localeId, debug) {
|
|
65
|
+
const siteBundleId = getSiteBundleId(moduleId, localeId, this.i18n);
|
|
66
|
+
return this.siteMetadata.getSiteBundlesDecisionTree().find(siteBundleId, debug);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Takes a key from the site bundle metadata and creates an appropriate runtime BaseModuleReference to use in the LWR runtime.
|
|
70
|
+
*/
|
|
71
|
+
getModuleReference(siteBundleIdStr, localeId, debug) {
|
|
72
|
+
const siteBundleId = parseSiteId(siteBundleIdStr);
|
|
73
|
+
const includedModule = explodeSpecifier(siteBundleId.specifier);
|
|
74
|
+
if (!siteBundleId.variants[VERSION_SIGIL]) {
|
|
75
|
+
const importBundleMetadata = this.siteMetadata
|
|
76
|
+
.getSiteBundlesDecisionTree()
|
|
77
|
+
.find(siteBundleIdStr, debug, localeId);
|
|
78
|
+
includedModule.version = resolveStaticBundleVersion(importBundleMetadata?.version);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
includedModule.version = siteBundleId.variants[VERSION_SIGIL];
|
|
82
|
+
}
|
|
83
|
+
return includedModule;
|
|
84
|
+
}
|
|
75
85
|
/**
|
|
76
86
|
* Get the source code for the a static bundle
|
|
77
87
|
* If we are running in a lambda and the mode is debug we will return the prod source code instead of the debug source code
|
|
@@ -81,17 +91,16 @@ export default class StaticBundleProvider {
|
|
|
81
91
|
* @param specifier Root specifier for the requested bundle
|
|
82
92
|
* @param localeId Locale id (e.g. en-US) for the current request
|
|
83
93
|
*/
|
|
84
|
-
async getCode(bundlePath, debug, specifier, localeId) {
|
|
94
|
+
async getCode(bundlePath, debug, specifier, version, localeId) {
|
|
85
95
|
// Flag is used to indicate that we are running on a lambda
|
|
86
|
-
const isLambda =
|
|
96
|
+
const isLambda = isLambdaEnv();
|
|
87
97
|
// Default source code path determined from metadata based on debug mode
|
|
88
98
|
let bundleSourcePath = bundlePath;
|
|
89
99
|
try {
|
|
90
100
|
// This is the special case where the request is in debug mode and we are on the lambda
|
|
91
101
|
// So we will look up the prod source code instead of the debug source code
|
|
92
102
|
if (debug && isLambda) {
|
|
93
|
-
const
|
|
94
|
-
const metadata = await getLocalizedBundle(specifier, siteBundles, localeId, this.i18n);
|
|
103
|
+
const metadata = this.getBundleMetadata({ specifier, version }, localeId, false);
|
|
95
104
|
if (!metadata) {
|
|
96
105
|
// We did not find the bundle prod bundle even though we did find it in the debug metadata before
|
|
97
106
|
logger.warn({
|
|
@@ -105,7 +114,7 @@ export default class StaticBundleProvider {
|
|
|
105
114
|
bundleSourcePath = path.join(this.siteRootDir, metadata.path);
|
|
106
115
|
}
|
|
107
116
|
// Read the bundle source code.
|
|
108
|
-
return
|
|
117
|
+
return await fs.readFile(bundleSourcePath, 'utf-8');
|
|
109
118
|
}
|
|
110
119
|
catch (err) {
|
|
111
120
|
// Ran it an un-expected error reading the bundle source code
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import type { AbstractModuleId, I18NConfig, ModuleCompiled, ModuleEntry, ModuleProvider, ProviderContext, RuntimeParams } from '@lwrjs/types';
|
|
1
|
+
import type { AbstractModuleId, I18NConfig, ModuleCompiled, ModuleEntry, ModuleProvider, ProviderContext, RuntimeParams, SiteMetadata } from '@lwrjs/types';
|
|
2
2
|
export default class StaticModuleProvider implements ModuleProvider {
|
|
3
3
|
name: string;
|
|
4
|
-
siteBundles: import("@lwrjs/types").SiteBundles;
|
|
5
4
|
siteRootDir: string;
|
|
6
5
|
externals: string[];
|
|
7
6
|
fingerprintIndex: Record<string, ModuleEntry>;
|
|
8
7
|
i18n: I18NConfig;
|
|
8
|
+
siteMetadata: SiteMetadata;
|
|
9
9
|
constructor(_config: {}, context: ProviderContext);
|
|
10
10
|
getModule<T extends AbstractModuleId>(moduleId: T, runtimeParams: RuntimeParams): Promise<ModuleCompiled | undefined>;
|
|
11
11
|
getModuleEntry<T extends AbstractModuleId>(moduleId: T, runtimeParams: RuntimeParams): Promise<ModuleEntry | undefined>;
|
|
12
|
+
private getEntryFromFingerprintIndex;
|
|
13
|
+
private getBundleMetadata;
|
|
12
14
|
}
|
|
13
15
|
//# sourceMappingURL=static-module-provider.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { logger } from '@lwrjs/diagnostics';
|
|
2
|
-
import { explodeSpecifier, getSpecifier } from '@lwrjs/shared-utils';
|
|
2
|
+
import { VERSION_SIGIL, explodeSpecifier, getSpecifier } from '@lwrjs/shared-utils';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import {
|
|
4
|
+
import { getSiteBundleId, parseSiteId, resolveStaticBundleVersion } from '../site-metadata.js';
|
|
5
5
|
export default class StaticModuleProvider {
|
|
6
6
|
constructor(_config, context) {
|
|
7
7
|
this.name = 'static-module-provider';
|
|
@@ -9,16 +9,15 @@ export default class StaticModuleProvider {
|
|
|
9
9
|
throw new Error(`[${this.name}] Site metadata was not found`);
|
|
10
10
|
}
|
|
11
11
|
this.externals = Object.keys(context.config.bundleConfig.external || {});
|
|
12
|
-
this.siteBundles = context.siteMetadata.getSiteBundles();
|
|
13
12
|
this.siteRootDir = context.siteMetadata.getSiteRootDir();
|
|
14
13
|
this.i18n = context.config.i18n;
|
|
14
|
+
this.siteMetadata = context.siteMetadata;
|
|
15
15
|
// If we are using fingerprints collect all the specifiers in the bundles and add them to an index for creating the mapping identities
|
|
16
16
|
this.fingerprintIndex = buildFingerprintsIndex(context);
|
|
17
17
|
}
|
|
18
18
|
async getModule(moduleId, runtimeParams) {
|
|
19
|
-
const { specifier } = moduleId;
|
|
20
19
|
const localeId = (runtimeParams?.locale || this.i18n.defaultLocale);
|
|
21
|
-
const metadata =
|
|
20
|
+
const metadata = this.getBundleMetadata(moduleId, localeId, false);
|
|
22
21
|
if (metadata) {
|
|
23
22
|
logger.warn({
|
|
24
23
|
label: `${this.name}`,
|
|
@@ -34,7 +33,7 @@ export default class StaticModuleProvider {
|
|
|
34
33
|
// TODO shouldn't we be passing the runtime environment here to test?
|
|
35
34
|
const { specifier, version } = moduleId;
|
|
36
35
|
const localeId = (runtimeParams?.locale || this.i18n.defaultLocale);
|
|
37
|
-
const metadata =
|
|
36
|
+
const metadata = this.getBundleMetadata(moduleId, localeId, false);
|
|
38
37
|
if (metadata) {
|
|
39
38
|
logger.debug({
|
|
40
39
|
label: `${this.name}`,
|
|
@@ -61,11 +60,16 @@ export default class StaticModuleProvider {
|
|
|
61
60
|
entry: 'entry-not-provided',
|
|
62
61
|
};
|
|
63
62
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
63
|
+
// checks the fingerprint index or proceeds to next provider
|
|
64
|
+
return this.getEntryFromFingerprintIndex(moduleId);
|
|
65
|
+
}
|
|
66
|
+
getEntryFromFingerprintIndex(moduleId) {
|
|
67
|
+
const versionedSpecifier = getSpecifier(moduleId);
|
|
68
|
+
return this.fingerprintIndex[versionedSpecifier] || this.fingerprintIndex[moduleId.specifier];
|
|
69
|
+
}
|
|
70
|
+
getBundleMetadata(moduleId, localeId, debug) {
|
|
71
|
+
const siteBundleId = getSiteBundleId(moduleId, localeId, this.i18n);
|
|
72
|
+
return this.siteMetadata.getSiteBundlesDecisionTree().find(siteBundleId, debug);
|
|
69
73
|
}
|
|
70
74
|
}
|
|
71
75
|
/**
|
|
@@ -80,10 +84,21 @@ function buildFingerprintsIndex(context) {
|
|
|
80
84
|
const bundlePath = path.join(String(context.siteMetadata?.getSiteRootDir()), bundle.path);
|
|
81
85
|
const includedModules = bundle.includedModules || [];
|
|
82
86
|
for (const includedModule of includedModules) {
|
|
83
|
-
const
|
|
87
|
+
const versionedSpecifier = convertSiteIdToVersionedSpecifier(includedModule);
|
|
88
|
+
const moduleId = explodeSpecifier(versionedSpecifier);
|
|
89
|
+
if (!fingerprintIndex[versionedSpecifier]) {
|
|
90
|
+
fingerprintIndex[versionedSpecifier] = {
|
|
91
|
+
id: versionedSpecifier,
|
|
92
|
+
version: resolveStaticBundleVersion(moduleId.version),
|
|
93
|
+
specifier: moduleId.specifier,
|
|
94
|
+
entry: 'entry-not-provided',
|
|
95
|
+
src: bundlePath,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
// Add an un-versioned match for the first hit
|
|
84
99
|
if (!fingerprintIndex[moduleId.specifier]) {
|
|
85
100
|
fingerprintIndex[moduleId.specifier] = {
|
|
86
|
-
id:
|
|
101
|
+
id: moduleId.specifier,
|
|
87
102
|
version: resolveStaticBundleVersion(moduleId.version),
|
|
88
103
|
specifier: moduleId.specifier,
|
|
89
104
|
entry: 'entry-not-provided',
|
|
@@ -95,4 +110,8 @@ function buildFingerprintsIndex(context) {
|
|
|
95
110
|
}
|
|
96
111
|
return fingerprintIndex;
|
|
97
112
|
}
|
|
113
|
+
function convertSiteIdToVersionedSpecifier(siteId) {
|
|
114
|
+
const parsedSiteId = parseSiteId(siteId);
|
|
115
|
+
return getSpecifier({ specifier: parsedSiteId.specifier, version: parsedSiteId.variants[VERSION_SIGIL] });
|
|
116
|
+
}
|
|
98
117
|
//# sourceMappingURL=static-module-provider.js.map
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import type { BootstrapRuntimeEnvironment, ProviderContext, ResourceDefinition, ResourceIdentifier, ResourceProvider } from '@lwrjs/types';
|
|
1
|
+
import type { BootstrapRuntimeEnvironment, ProviderContext, ResourceDefinition, ResourceIdentifier, ResourceProvider, RuntimeParams } from '@lwrjs/types';
|
|
2
2
|
export default class StaticResourceProvider implements ResourceProvider {
|
|
3
3
|
name: string;
|
|
4
|
-
siteResources: import("@lwrjs/types").SiteResources;
|
|
5
|
-
debugSiteResources: import("@lwrjs/types").SiteResources;
|
|
6
4
|
siteRootDir: string;
|
|
5
|
+
siteMetadata: import("@lwrjs/types").SiteMetadata;
|
|
7
6
|
resourceRegistry: import("@lwrjs/types").PublicResourceRegistry;
|
|
8
7
|
constructor(_config: {}, context: ProviderContext);
|
|
9
|
-
getResource<Identifier extends ResourceIdentifier, RuntimeEnvironment extends BootstrapRuntimeEnvironment>(resourceIdentity: Identifier, runtimeEnvironment: RuntimeEnvironment): Promise<ResourceDefinition | undefined>;
|
|
8
|
+
getResource<Identifier extends ResourceIdentifier, RuntimeEnvironment extends BootstrapRuntimeEnvironment>(resourceIdentity: Identifier, runtimeEnvironment: RuntimeEnvironment, runtimeParams: RuntimeParams): Promise<ResourceDefinition | undefined>;
|
|
10
9
|
}
|
|
11
10
|
//# sourceMappingURL=static-resource-provider.d.ts.map
|
|
@@ -2,6 +2,7 @@ import { logger } from '@lwrjs/diagnostics';
|
|
|
2
2
|
import { mimeLookup } from '@lwrjs/shared-utils';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import fs from 'fs-extra';
|
|
5
|
+
import { getSiteResourceId } from '../site-metadata.js';
|
|
5
6
|
export default class StaticResourceProvider {
|
|
6
7
|
constructor(_config, context) {
|
|
7
8
|
this.name = 'static-resource-provider';
|
|
@@ -9,50 +10,43 @@ export default class StaticResourceProvider {
|
|
|
9
10
|
throw new Error(`[${this.name}] Site metadata was not found`);
|
|
10
11
|
}
|
|
11
12
|
this.resourceRegistry = context.resourceRegistry;
|
|
12
|
-
this.siteResources = context.siteMetadata.getSiteResources();
|
|
13
|
-
this.debugSiteResources = context.siteMetadata.getDebugSiteResources();
|
|
14
13
|
this.siteRootDir = context.siteMetadata.getSiteRootDir();
|
|
14
|
+
this.siteMetadata = context.siteMetadata;
|
|
15
15
|
}
|
|
16
|
-
async getResource(resourceIdentity, runtimeEnvironment) {
|
|
16
|
+
async getResource(resourceIdentity, runtimeEnvironment, runtimeParams) {
|
|
17
17
|
const { debug } = runtimeEnvironment;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
// HACK: this code is tricky because resource IDs are different between prod vs debug ("lwr-loader-shim.bundle.min.js" vs "lwr-loader-shim.bundle.js").
|
|
19
|
+
// 1. In debug mode on Lambda (during SSR), we need to ignore runtimeEnvironment.debug because we will always ask for the prod version (lwr-loader-shim.bundle.min.js)
|
|
20
|
+
// 2. But when we generate the view, we can't ignore runtimeEnvironment.debug because we need the debug version of the loader shim (lwr-loader-shim.bundle.js)
|
|
21
|
+
const { ignoreDebug } = runtimeParams;
|
|
22
|
+
const resourceMetadata = this.siteMetadata
|
|
23
|
+
.getSiteResourcesDecisionTree()
|
|
24
|
+
.find(getSiteResourceId(resourceIdentity), debug && !ignoreDebug);
|
|
25
|
+
if (!resourceMetadata) {
|
|
23
26
|
logger.warn({
|
|
24
27
|
label: `${this.name}`,
|
|
25
28
|
message: `Did not find requested specifier ${resourceIdentity.specifier}`,
|
|
26
29
|
});
|
|
27
30
|
return undefined;
|
|
28
31
|
}
|
|
29
|
-
const resourcePath = path.join(this.siteRootDir,
|
|
30
|
-
const debugResourcePath = debugMetadata ? path.join(this.siteRootDir, debugMetadata.path) : undefined;
|
|
31
|
-
const isLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined;
|
|
32
|
-
const useDebug = debug && !isLambda && debugResourcePath;
|
|
32
|
+
const resourcePath = path.join(this.siteRootDir, resourceMetadata.path);
|
|
33
33
|
// Figure out mime type
|
|
34
|
-
const type =
|
|
34
|
+
const type = resourceMetadata.mimeType ||
|
|
35
|
+
mimeLookup(resourcePath) ||
|
|
36
|
+
'application/javascript';
|
|
35
37
|
return {
|
|
36
38
|
type,
|
|
37
|
-
// Have to make the loader shim code available for SSR
|
|
38
39
|
stream: () => {
|
|
39
40
|
logger.debug({
|
|
40
41
|
label: `${this.name}`,
|
|
41
42
|
message: `Resource read from lambda ${resourceIdentity.specifier}`,
|
|
42
43
|
});
|
|
43
|
-
|
|
44
|
-
// use the debug resource if:
|
|
45
|
-
// - debug mode is ON
|
|
46
|
-
// - isLambda is false
|
|
47
|
-
// - the debug version of the resource exists
|
|
48
|
-
return fs.createReadStream(debugResourcePath);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
return fs.createReadStream(resourcePath);
|
|
52
|
-
}
|
|
44
|
+
return fs.createReadStream(resourcePath);
|
|
53
45
|
},
|
|
54
|
-
src:
|
|
55
|
-
inline:
|
|
46
|
+
src: resourcePath,
|
|
47
|
+
inline: resourceMetadata.inline,
|
|
48
|
+
integrity: resourceMetadata.integrity,
|
|
49
|
+
entry: path.resolve(resourcePath),
|
|
56
50
|
};
|
|
57
51
|
}
|
|
58
52
|
}
|
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
import type { SiteAssets, SiteBundles, SiteMetadata, SiteResources } from '@lwrjs/types';
|
|
1
|
+
import type { AbstractModuleId, I18NConfig, ResourceIdentifier, SiteAssets, SiteBundle, SiteBundles, SiteMetadata, SiteResource, SiteResources } from '@lwrjs/types';
|
|
2
|
+
import DecisionTree from './utils/decision-tree.js';
|
|
3
|
+
import { LOCALE_SIGIL, VERSION_SIGIL } from '@lwrjs/shared-utils';
|
|
2
4
|
type Options = {
|
|
3
5
|
rootDir: string;
|
|
6
|
+
i18n: I18NConfig;
|
|
4
7
|
};
|
|
8
|
+
export declare const SITE_VERSION_PREFIX: string;
|
|
9
|
+
export declare const SITE_LOCALE_PREFIX: string;
|
|
10
|
+
type SIGIL = typeof VERSION_SIGIL | typeof LOCALE_SIGIL;
|
|
11
|
+
interface SiteArtifactId {
|
|
12
|
+
specifier: string;
|
|
13
|
+
variants: Record<SIGIL, string>;
|
|
14
|
+
}
|
|
5
15
|
export declare class SiteMetadataImpl implements SiteMetadata {
|
|
6
16
|
private options;
|
|
7
17
|
private siteBundles;
|
|
@@ -9,6 +19,8 @@ export declare class SiteMetadataImpl implements SiteMetadata {
|
|
|
9
19
|
private siteResources;
|
|
10
20
|
private debugSiteResources;
|
|
11
21
|
private siteAssets;
|
|
22
|
+
private bundleDecisionTree?;
|
|
23
|
+
private resourceDecisionTree?;
|
|
12
24
|
constructor(options: Options);
|
|
13
25
|
getSiteRootDir(): string;
|
|
14
26
|
getSiteBundles(): SiteBundles;
|
|
@@ -16,6 +28,16 @@ export declare class SiteMetadataImpl implements SiteMetadata {
|
|
|
16
28
|
getSiteResources(): SiteResources;
|
|
17
29
|
getDebugSiteResources(): SiteResources;
|
|
18
30
|
getSiteAssets(): SiteAssets;
|
|
31
|
+
/**
|
|
32
|
+
* Returns a decision tree for site bundles in the form [debug, specifier, version, locale].
|
|
33
|
+
* It is assumed this is static after creation subsequent calls will return the same instance.
|
|
34
|
+
*/
|
|
35
|
+
getSiteBundlesDecisionTree(): DecisionTree<SiteBundle>;
|
|
36
|
+
/**
|
|
37
|
+
* Returns a decision tree for site resources.
|
|
38
|
+
* It is assumed this is static after creation subsequent calls will return the same instance.
|
|
39
|
+
*/
|
|
40
|
+
getSiteResourcesDecisionTree(): DecisionTree<SiteResource>;
|
|
19
41
|
persistSiteMetadata(): Promise<void>;
|
|
20
42
|
private readStaticBundleMetadata;
|
|
21
43
|
/**
|
|
@@ -27,5 +49,30 @@ export declare class SiteMetadataImpl implements SiteMetadata {
|
|
|
27
49
|
*/
|
|
28
50
|
private readStaticAssetsMetadata;
|
|
29
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Return the version for a static module bundle.
|
|
54
|
+
*
|
|
55
|
+
* Version defined in the metadata > Requested Version > 'version-not-provided'
|
|
56
|
+
*/
|
|
57
|
+
export declare function resolveStaticBundleVersion(metadataVersion?: string, requestedVersion?: string): string;
|
|
58
|
+
/**
|
|
59
|
+
* Parse a site artifact ids string in the form specifier(|sigil(/value)?)*
|
|
60
|
+
*/
|
|
61
|
+
export declare function parseSiteId(input: string): SiteArtifactId;
|
|
62
|
+
/**
|
|
63
|
+
* Get a Site Bundle Identifier from a Root Module
|
|
64
|
+
*
|
|
65
|
+
* @param moduleId - Root Module Id
|
|
66
|
+
* @param locale - Current locale
|
|
67
|
+
* @returns Site Bundle Identifier
|
|
68
|
+
*/
|
|
69
|
+
export declare function getSiteBundleId({ specifier, namespace, name, version }: Partial<AbstractModuleId>, locale?: string, i18n?: I18NConfig): string;
|
|
70
|
+
/**
|
|
71
|
+
* Get a Site Resource Identifier from a Resource Identifier
|
|
72
|
+
*
|
|
73
|
+
* @param resourceID -Resource Identifier
|
|
74
|
+
* @returns Site Bundle Identifier
|
|
75
|
+
*/
|
|
76
|
+
export declare function getSiteResourceId({ specifier, version }: Partial<ResourceIdentifier>): string;
|
|
30
77
|
export {};
|
|
31
78
|
//# sourceMappingURL=site-metadata.d.ts.map
|