@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.
@@ -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
+ }
@@ -0,0 +1,2 @@
1
+ export * from './tools/dedupe-bundles.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export * from './tools/dedupe-bundles.js';
2
+ //# sourceMappingURL=index.js.map
@@ -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 { getLocalizedBundle, resolveStaticBundleVersion } from '../utils/static-utils.js';
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.siteBundles = context.siteMetadata.getSiteBundles();
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 siteBundles = debug && this.debugSiteBundles ? this.debugSiteBundles : this.siteBundles;
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((specifier) => {
32
- const importModule = explodeSpecifier(specifier);
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 || exploded.name;
51
- const resolvedNamespace = namespace || exploded.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: metadata.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 = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined;
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 siteBundles = this.siteBundles;
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 (await fs.readFile(bundleSourcePath)).toString('utf-8');
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 { getLocalizedBundle, resolveStaticBundleVersion } from '../utils/static-utils.js';
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 = await getLocalizedBundle(specifier, this.siteBundles, localeId, this.i18n);
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 = await getLocalizedBundle(specifier, this.siteBundles, localeId, this.i18n);
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
- else if (this.fingerprintIndex[specifier]) {
65
- return this.fingerprintIndex[specifier];
66
- }
67
- // proceed to next provider
68
- return undefined;
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 moduleId = explodeSpecifier(includedModule);
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: getSpecifier(moduleId),
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
- const metadata = this.siteResources.resources[resourceIdentity.specifier];
19
- const debugMetadata = this.debugSiteResources
20
- ? this.debugSiteResources.resources[resourceIdentity.specifier]
21
- : undefined;
22
- if (!metadata && !debugMetadata) {
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, metadata.path);
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 = metadata.mimeType || mimeLookup(resourcePath) || 'application/javascript';
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
- if (useDebug) {
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: useDebug ? debugResourcePath : resourcePath,
55
- inline: metadata.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