@lwrjs/static 0.15.0-alpha.17 → 0.15.0-alpha.18

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.
@@ -30,9 +30,11 @@ var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
30
30
  var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
31
31
  var import_path = __toModule(require("path"));
32
32
  var import_fs_extra = __toModule(require("fs-extra"));
33
+ var import_lru_cache = __toModule(require("lru-cache"));
33
34
  var import_site_metadata = __toModule(require("../site-metadata.cjs"));
35
+ var BUNDLE_SOURCE_NOT_FOUND = "Bundle Source Path Not Found";
34
36
  var StaticBundleProvider = class {
35
- constructor(_config, context) {
37
+ constructor(config, context) {
36
38
  this.name = "static-bundle-provider";
37
39
  if (!context.siteMetadata) {
38
40
  throw new Error(`[${this.name}] Site metadata was not found`);
@@ -41,6 +43,15 @@ var StaticBundleProvider = class {
41
43
  this.siteRootDir = context.siteMetadata.getSiteRootDir();
42
44
  this.bundleConfig = context.config.bundleConfig;
43
45
  this.i18n = context.config.i18n;
46
+ this.bundleCacheSize = config.bundleCacheSize ?? parseInt(process.env.BUNDLE_CACHE_SIZE ?? "500", 10);
47
+ if (this.bundleCacheSize > 0) {
48
+ this.codeCache = new import_lru_cache.LRUCache({
49
+ max: this.bundleCacheSize,
50
+ dispose: (_value, key) => {
51
+ import_diagnostics.logger.verbose(`Bundle Code evicted from cache ${key}`);
52
+ }
53
+ });
54
+ }
44
55
  }
45
56
  async bundle(moduleId, runtimeEnvironment, runtimeParams) {
46
57
  const {specifier, name, namespace, version} = moduleId;
@@ -55,7 +66,8 @@ var StaticBundleProvider = class {
55
66
  }
56
67
  const bundlePath = import_path.default.join(this.siteRootDir, metadata.path);
57
68
  const ssr = runtimeParams?.ssr;
58
- const code = await this.getCode(bundlePath, debug, specifier, version, localeId, ssr);
69
+ const resolvedBundlePath = this.getCodePath(bundlePath, debug, specifier, version, localeId, ssr);
70
+ const codePromiser = this.getCodePromiser(resolvedBundlePath, specifier);
59
71
  const imports = metadata.imports.map((importSpecifier) => this.getModuleReference(importSpecifier, localeId, debug, false));
60
72
  const dynamicImports = metadata.dynamicImports?.map((importSpecifier) => this.getModuleReference(importSpecifier, localeId, debug, false));
61
73
  const id = (0, import_shared_utils.getSpecifier)(moduleId);
@@ -68,7 +80,7 @@ var StaticBundleProvider = class {
68
80
  return (0, import_shared_utils.getSpecifier)(includedModule);
69
81
  }) || [];
70
82
  return {
71
- code,
83
+ getCode: codePromiser,
72
84
  id: (0, import_shared_utils.getSpecifier)({
73
85
  specifier,
74
86
  version: resolvedVersion,
@@ -109,44 +121,63 @@ var StaticBundleProvider = class {
109
121
  }
110
122
  return includedModule;
111
123
  }
112
- async getCode(bundlePath, debug, specifier, version, localeId, ssr) {
113
- const isLambda = (0, import_shared_utils.isLambdaEnv)();
114
- let bundleSourcePath = bundlePath;
115
- try {
116
- if (debug && isLambda) {
117
- const metadata = this.getBundleMetadata({
118
- moduleId: {specifier, version},
119
- localeId,
120
- debug: false,
121
- ssr
122
- });
123
- if (!metadata) {
124
+ getCodePromiser(bundleSourcePath, specifier) {
125
+ const cache = this.codeCache;
126
+ return async () => {
127
+ let code = cache?.get(bundleSourcePath);
128
+ if (!code) {
129
+ try {
130
+ if (bundleSourcePath === BUNDLE_SOURCE_NOT_FOUND) {
131
+ throw new Error(BUNDLE_SOURCE_NOT_FOUND);
132
+ }
133
+ code = await import_fs_extra.default.readFile(import_path.default.join(bundleSourcePath), "utf-8");
134
+ if (cache) {
135
+ cache.set(bundleSourcePath, code);
136
+ }
137
+ } catch (err) {
124
138
  import_diagnostics.logger.warn({
125
139
  label: "static-bundle-provider",
126
- message: `Unexpected code reference: ${specifier}`
127
- });
128
- return `throw new Error('Unexpected code reference: ${specifier}');`;
140
+ message: `Unexpected code reference: ${specifier} ${bundleSourcePath}`
141
+ }, err);
142
+ code = `throw new Error('Unexpected code reference: ${specifier} ${bundleSourcePath}');`;
143
+ if (cache) {
144
+ cache.set(bundleSourcePath, code);
145
+ }
129
146
  }
130
- bundleSourcePath = import_path.default.join(this.siteRootDir, metadata.path);
131
- } else if (ssr) {
132
- const metadata = this.getBundleMetadata({
133
- moduleId: {specifier, version},
134
- localeId,
135
- debug,
136
- ssr
147
+ }
148
+ return code;
149
+ };
150
+ }
151
+ getCodePath(bundlePath, debug, specifier, version, localeId, ssr) {
152
+ const isLambda = (0, import_shared_utils.isLambdaEnv)();
153
+ let bundleSourcePath = bundlePath;
154
+ if (debug && isLambda) {
155
+ const metadata = this.getBundleMetadata({
156
+ moduleId: {specifier, version},
157
+ localeId,
158
+ debug: false,
159
+ ssr
160
+ });
161
+ if (!metadata) {
162
+ import_diagnostics.logger.error({
163
+ label: "static-bundle-provider",
164
+ message: `Unexpected code reference: ${specifier}`
137
165
  });
138
- if (metadata) {
139
- bundleSourcePath = import_path.default.join(this.siteRootDir, metadata.path);
140
- }
166
+ return BUNDLE_SOURCE_NOT_FOUND;
167
+ }
168
+ bundleSourcePath = import_path.default.join(this.siteRootDir, metadata.path);
169
+ } else if (ssr) {
170
+ const metadata = this.getBundleMetadata({
171
+ moduleId: {specifier, version},
172
+ localeId,
173
+ debug,
174
+ ssr
175
+ });
176
+ if (metadata) {
177
+ bundleSourcePath = import_path.default.join(this.siteRootDir, metadata.path);
141
178
  }
142
- return await import_fs_extra.default.readFile(bundleSourcePath, "utf-8");
143
- } catch (err) {
144
- import_diagnostics.logger.warn({
145
- label: "static-bundle-provider",
146
- message: `Unexpected code reference: ${specifier} ${bundleSourcePath}`
147
- }, err);
148
- return `throw new Error('Unexpected code reference: ${specifier} ${bundleSourcePath}');`;
149
179
  }
180
+ return bundleSourcePath;
150
181
  }
151
182
  };
152
183
  var static_bundle_provider_default = StaticBundleProvider;
@@ -1,11 +1,16 @@
1
1
  import type { AbstractModuleId, BundleDefinition, BundleProvider, ProviderContext, RuntimeEnvironment, RuntimeParams, SiteBundle, SiteMetadata } from '@lwrjs/types';
2
+ import { LRUCache } from 'lru-cache';
2
3
  export default class StaticBundleProvider implements BundleProvider {
3
4
  name: string;
5
+ codeCache: LRUCache<string, string, unknown> | undefined;
4
6
  siteRootDir: string;
5
7
  bundleConfig: import("@lwrjs/types").BundleConfig;
6
8
  i18n: import("@lwrjs/types").I18NConfig;
7
9
  siteMetadata: SiteMetadata;
8
- constructor(_config: {}, context: ProviderContext);
10
+ bundleCacheSize: number;
11
+ constructor(config: {
12
+ bundleCacheSize?: number;
13
+ }, context: ProviderContext);
9
14
  bundle<BundleIdentifier extends AbstractModuleId, RE extends RuntimeEnvironment>(moduleId: BundleIdentifier, runtimeEnvironment: RE, runtimeParams: RuntimeParams): Promise<BundleDefinition | undefined>;
10
15
  getBundleMetadata({ moduleId, localeId, debug, ssr, }: {
11
16
  moduleId: Partial<AbstractModuleId>;
@@ -17,8 +22,9 @@ export default class StaticBundleProvider implements BundleProvider {
17
22
  * Takes a key from the site bundle metadata and creates an appropriate runtime BaseModuleReference to use in the LWR runtime.
18
23
  */
19
24
  private getModuleReference;
25
+ getCodePromiser(bundleSourcePath: string, specifier: string): () => Promise<string>;
20
26
  /**
21
- * Get the source code for the a static bundle
27
+ * Get the local source code path for the a static bundle
22
28
  * 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
23
29
  *
24
30
  * @param bundlePath The default path for the bundle for prod read from .metadata/bundle-metadata.json, for debug .metadata/bundle-metadata-debug.json
@@ -26,6 +32,6 @@ export default class StaticBundleProvider implements BundleProvider {
26
32
  * @param specifier Root specifier for the requested bundle
27
33
  * @param localeId Locale id (e.g. en-US) for the current request
28
34
  */
29
- getCode(bundlePath: string, debug: boolean, specifier: string, version: string | undefined, localeId: string, ssr: boolean): Promise<string>;
35
+ getCodePath(bundlePath: string, debug: boolean, specifier: string, version: string | undefined, localeId: string, ssr: boolean): string;
30
36
  }
31
37
  //# sourceMappingURL=static-bundle-provider.d.ts.map
@@ -2,9 +2,11 @@ import { logger } from '@lwrjs/diagnostics';
2
2
  import { VERSION_SIGIL, explodeSpecifier, getSpecifier, isLambdaEnv } from '@lwrjs/shared-utils';
3
3
  import path from 'path';
4
4
  import fs from 'fs-extra';
5
+ import { LRUCache } from 'lru-cache';
5
6
  import { getSiteBundleId, parseSiteId, resolveStaticBundleVersion } from '../site-metadata.js';
7
+ const BUNDLE_SOURCE_NOT_FOUND = 'Bundle Source Path Not Found';
6
8
  export default class StaticBundleProvider {
7
- constructor(_config, context) {
9
+ constructor(config, context) {
8
10
  this.name = 'static-bundle-provider';
9
11
  if (!context.siteMetadata) {
10
12
  throw new Error(`[${this.name}] Site metadata was not found`);
@@ -13,6 +15,15 @@ export default class StaticBundleProvider {
13
15
  this.siteRootDir = context.siteMetadata.getSiteRootDir();
14
16
  this.bundleConfig = context.config.bundleConfig;
15
17
  this.i18n = context.config.i18n;
18
+ this.bundleCacheSize = config.bundleCacheSize ?? parseInt(process.env.BUNDLE_CACHE_SIZE ?? '500', 10);
19
+ if (this.bundleCacheSize > 0) {
20
+ this.codeCache = new LRUCache({
21
+ max: this.bundleCacheSize,
22
+ dispose: (_value, key) => {
23
+ logger.verbose(`Bundle Code evicted from cache ${key}`);
24
+ },
25
+ });
26
+ }
16
27
  }
17
28
  async bundle(moduleId, runtimeEnvironment, runtimeParams) {
18
29
  const { specifier, name, namespace, version } = moduleId;
@@ -28,7 +39,8 @@ export default class StaticBundleProvider {
28
39
  const bundlePath = path.join(this.siteRootDir, metadata.path);
29
40
  // Get the associated bundle source code
30
41
  const ssr = runtimeParams?.ssr;
31
- const code = await this.getCode(bundlePath, debug, specifier, version, localeId, ssr);
42
+ const resolvedBundlePath = this.getCodePath(bundlePath, debug, specifier, version, localeId, ssr);
43
+ const codePromiser = this.getCodePromiser(resolvedBundlePath, specifier);
32
44
  const imports = metadata.imports.map((importSpecifier) => this.getModuleReference(importSpecifier, localeId, debug, false));
33
45
  const dynamicImports = metadata.dynamicImports?.map((importSpecifier) => this.getModuleReference(importSpecifier, localeId, debug, false));
34
46
  const id = getSpecifier(moduleId);
@@ -42,7 +54,7 @@ export default class StaticBundleProvider {
42
54
  return getSpecifier(includedModule);
43
55
  }) || [];
44
56
  return {
45
- code,
57
+ getCode: codePromiser,
46
58
  id: getSpecifier({
47
59
  specifier: specifier,
48
60
  version: resolvedVersion,
@@ -85,8 +97,39 @@ export default class StaticBundleProvider {
85
97
  }
86
98
  return includedModule;
87
99
  }
100
+ getCodePromiser(bundleSourcePath, specifier) {
101
+ const cache = this.codeCache;
102
+ return async () => {
103
+ let code = cache?.get(bundleSourcePath);
104
+ if (!code) {
105
+ try {
106
+ // Debug metadata was not found
107
+ if (bundleSourcePath === BUNDLE_SOURCE_NOT_FOUND) {
108
+ throw new Error(BUNDLE_SOURCE_NOT_FOUND);
109
+ }
110
+ code = await fs.readFile(path.join(bundleSourcePath), 'utf-8');
111
+ if (cache) {
112
+ cache.set(bundleSourcePath, code);
113
+ }
114
+ }
115
+ catch (err) {
116
+ // Ran it an un-expected error reading the bundle source code
117
+ logger.warn({
118
+ label: 'static-bundle-provider',
119
+ message: `Unexpected code reference: ${specifier} ${bundleSourcePath}`,
120
+ }, err);
121
+ // Returning source code that throws and error is someone tries to evaluate it
122
+ code = `throw new Error('Unexpected code reference: ${specifier} ${bundleSourcePath}');`;
123
+ if (cache) {
124
+ cache.set(bundleSourcePath, code);
125
+ }
126
+ }
127
+ }
128
+ return code;
129
+ };
130
+ }
88
131
  /**
89
- * Get the source code for the a static bundle
132
+ * Get the local source code path for the a static bundle
90
133
  * 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
91
134
  *
92
135
  * @param bundlePath The default path for the bundle for prod read from .metadata/bundle-metadata.json, for debug .metadata/bundle-metadata-debug.json
@@ -94,58 +137,45 @@ export default class StaticBundleProvider {
94
137
  * @param specifier Root specifier for the requested bundle
95
138
  * @param localeId Locale id (e.g. en-US) for the current request
96
139
  */
97
- async getCode(bundlePath, debug, specifier, version, localeId, ssr) {
140
+ getCodePath(bundlePath, debug, specifier, version, localeId, ssr) {
98
141
  // Flag is used to indicate that we are running on a lambda
99
142
  const isLambda = isLambdaEnv();
100
143
  // Default source code path determined from metadata based on debug mode
101
144
  let bundleSourcePath = bundlePath;
102
- try {
103
- // This is the special case where the request is in debug mode and we are on the lambda
104
- // So we will look up the prod source code instead of the debug source code
105
- if (debug && isLambda) {
106
- const metadata = this.getBundleMetadata({
107
- moduleId: { specifier, version },
108
- localeId,
109
- debug: false,
110
- ssr,
145
+ // This is the special case where the request is in debug mode and we are on the lambda
146
+ // So we will look up the prod source code instead of the debug source code
147
+ if (debug && isLambda) {
148
+ const metadata = this.getBundleMetadata({
149
+ moduleId: { specifier, version },
150
+ localeId,
151
+ debug: false,
152
+ ssr,
153
+ });
154
+ if (!metadata) {
155
+ // We did not find the bundle prod bundle even though we did find it in the debug metadata before
156
+ logger.error({
157
+ label: 'static-bundle-provider',
158
+ message: `Unexpected code reference: ${specifier}`,
111
159
  });
112
- if (!metadata) {
113
- // We did not find the bundle prod bundle even though we did find it in the debug metadata before
114
- logger.warn({
115
- label: 'static-bundle-provider',
116
- message: `Unexpected code reference: ${specifier}`,
117
- });
118
- // Returning source code that throws and error is someone tries to evaluate it
119
- return `throw new Error('Unexpected code reference: ${specifier}');`;
120
- }
121
- // Overwrite the default source code path the prod source code path
122
- bundleSourcePath = path.join(this.siteRootDir, metadata.path);
160
+ return BUNDLE_SOURCE_NOT_FOUND;
123
161
  }
124
- else if (ssr) {
125
- // If this is an ssr request get the code preferring bifurcated ssr modules
126
- const metadata = this.getBundleMetadata({
127
- moduleId: { specifier, version },
128
- localeId,
129
- debug,
130
- ssr,
131
- });
132
- if (metadata) {
133
- // Overwrite the default source code path the ssr source code path
134
- bundleSourcePath = path.join(this.siteRootDir, metadata.path);
135
- }
136
- }
137
- // Read the bundle source code.
138
- return await fs.readFile(bundleSourcePath, 'utf-8');
162
+ // Overwrite the default source code path the prod source code path
163
+ bundleSourcePath = path.join(this.siteRootDir, metadata.path);
139
164
  }
140
- catch (err) {
141
- // Ran it an un-expected error reading the bundle source code
142
- logger.warn({
143
- label: 'static-bundle-provider',
144
- message: `Unexpected code reference: ${specifier} ${bundleSourcePath}`,
145
- }, err);
146
- // Returning source code that throws and error is someone tries to evaluate it
147
- return `throw new Error('Unexpected code reference: ${specifier} ${bundleSourcePath}');`;
165
+ else if (ssr) {
166
+ // If this is an ssr request get the code preferring bifurcated ssr modules
167
+ const metadata = this.getBundleMetadata({
168
+ moduleId: { specifier, version },
169
+ localeId,
170
+ debug,
171
+ ssr,
172
+ });
173
+ if (metadata) {
174
+ // Overwrite the default source code path the ssr source code path
175
+ bundleSourcePath = path.join(this.siteRootDir, metadata.path);
176
+ }
148
177
  }
178
+ return bundleSourcePath;
149
179
  }
150
180
  }
151
181
  //# sourceMappingURL=static-bundle-provider.js.map
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.15.0-alpha.17",
7
+ "version": "0.15.0-alpha.18",
8
8
  "homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
9
9
  "repository": {
10
10
  "type": "git",
@@ -52,14 +52,15 @@
52
52
  "build/**/*.d.ts"
53
53
  ],
54
54
  "dependencies": {
55
- "@lwrjs/diagnostics": "0.15.0-alpha.17",
56
- "@lwrjs/shared-utils": "0.15.0-alpha.17"
55
+ "@lwrjs/diagnostics": "0.15.0-alpha.18",
56
+ "@lwrjs/shared-utils": "0.15.0-alpha.18"
57
57
  },
58
58
  "devDependencies": {
59
- "@lwrjs/types": "0.15.0-alpha.17",
59
+ "@lwrjs/types": "0.15.0-alpha.18",
60
60
  "@types/express": "^4.17.21",
61
61
  "jest": "^26.6.3",
62
62
  "jest-express": "^1.12.0",
63
+ "lru-cache": "^10.4.3",
63
64
  "memfs": "^4.9.3",
64
65
  "mock-res": "^0.6.0",
65
66
  "ts-jest": "^26.5.6"
@@ -70,5 +71,5 @@
70
71
  "volta": {
71
72
  "extends": "../../../package.json"
72
73
  },
73
- "gitHead": "57b524a9be3a50ee50b7f6979a01bae458d09747"
74
+ "gitHead": "fefc639770948be769b1ace03b7759e7b8906cae"
74
75
  }