oc 0.50.58 → 0.50.59

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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ## Change Log
2
2
 
3
+ ## 0.50.59
4
+
5
+ ### Patch Changes
6
+
7
+ - adae2e2: remove final slash on oc.build
8
+ - Updated dependencies [adae2e2]
9
+ - oc-client-browser@2.1.12
10
+
3
11
  ## 0.50.58
4
12
 
5
13
  ### Patch Changes
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "oc-client",
3
3
  "description": "The OpenComponents client-side javascript client",
4
- "version": "0.50.58",
4
+ "version": "0.50.59",
5
5
  "repository": "https://github.com/opencomponents/oc/tree/master/components/oc-client",
6
6
  "author": "Matteo Figus <matteofigus@gmail.com>",
7
7
  "oc": {
@@ -23,14 +23,14 @@
23
23
  ],
24
24
  "dataProvider": {
25
25
  "type": "node.js",
26
- "hashKey": "6610c77b87178eeba18b0b4416b061df63aa0a6b",
26
+ "hashKey": "5ab7cad2df725598783ffb4c946d9db3fd1e65d4",
27
27
  "src": "server.js",
28
28
  "size": 644
29
29
  }
30
30
  },
31
- "version": "0.50.58",
31
+ "version": "0.50.59",
32
32
  "packaged": true,
33
- "date": 1784011980369
33
+ "date": 1784820712757
34
34
  },
35
35
  "devDependencies": {
36
36
  "oc-template-es6-compiler": "^8.0.0"
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=(t,s)=>{const{staticPath:e,templates:a}=t;return s(null,{staticPath:e,templates:a})},r=(t,s)=>{o(t,(e,a,i={})=>{if(e)return s(e);if(a==null)return s(null,{__oc_emptyResponse:!0});const n=t.action?a:Object.assign({},a,{_staticPath:t.staticPath,_baseUrl:t.baseUrl,_componentName:"oc-client",_componentVersion:"0.50.58"}),c=t.staticPath.indexOf("http")===0?t.staticPath:"https:"+t.staticPath;return s(null,Object.assign({},{component:{key:"c4abb6bf4dc6657fb718a45b64bd6b2cb92e874a",src:c+"template.js",props:n,esm:!1,development:void 0}}))})};exports.data=r;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=(t,s)=>{const{staticPath:e,templates:a}=t;return s(null,{staticPath:e,templates:a})},r=(t,s)=>{o(t,(e,a,i={})=>{if(e)return s(e);if(a==null)return s(null,{__oc_emptyResponse:!0});const n=t.action?a:Object.assign({},a,{_staticPath:t.staticPath,_baseUrl:t.baseUrl,_componentName:"oc-client",_componentVersion:"0.50.59"}),c=t.staticPath.indexOf("http")===0?t.staticPath:"https:"+t.staticPath;return s(null,Object.assign({},{component:{key:"c4abb6bf4dc6657fb718a45b64bd6b2cb92e874a",src:c+"template.js",props:n,esm:!1,development:void 0}}))})};exports.data=r;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "oc-client",
3
3
  "description": "The OpenComponents client-side javascript client",
4
- "version": "0.50.58",
4
+ "version": "0.50.59",
5
5
  "repository": "https://github.com/opencomponents/oc/tree/master/components/oc-client",
6
6
  "author": "Matteo Figus <matteofigus@gmail.com>",
7
7
  "oc": {
@@ -47,6 +47,7 @@ type Events = {
47
47
  };
48
48
  type EventsHandler = {
49
49
  fire<T extends keyof Events>(eventName: T, data: Events[T]): void;
50
+ hasListeners<T extends keyof Events>(eventName: T): boolean;
50
51
  on<T extends keyof Events>(eventName: T, listener: Subscription<Events[T]>): void;
51
52
  off<T extends keyof Events>(eventName: T, listener: Subscription<Events[T]>): void;
52
53
  reset(): void;
@@ -13,6 +13,9 @@ const eventsHandler = {
13
13
  }
14
14
  }
15
15
  },
16
+ hasListeners(eventName) {
17
+ return Boolean(subscriptions[eventName]?.length);
18
+ },
16
19
  on(eventName, callback) {
17
20
  if (typeof callback !== 'function') {
18
21
  throw resources_1.default.errors.registry.CONFIGURATION_ONREQUEST_MUST_BE_FUNCTION;
@@ -65,7 +65,13 @@ class ExpressHttpServerAdapter {
65
65
  filename: (_req, file, cb) => cb(null, opts.filename(file.originalname))
66
66
  })
67
67
  });
68
- this.app.use(upload.any());
68
+ const parseUpload = upload.any();
69
+ this.app.use((req, res, next) => {
70
+ if (req.method !== 'PUT') {
71
+ return next();
72
+ }
73
+ parseUpload(req, res, next);
74
+ });
69
75
  }
70
76
  enableRequestTiming(onDone) {
71
77
  this.app.use((0, response_time_1.default)((req, res, time) => {
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.default = nestedRenderer;
7
7
  const resources_1 = __importDefault(require("../../resources"));
8
8
  const settings_1 = __importDefault(require("../../resources/settings"));
9
+ const pLimit_1 = __importDefault(require("../../utils/pLimit"));
9
10
  function nestedRenderer(rendererWithCallback, conf) {
10
11
  const renderer = (options) => new Promise((res, rej) => {
11
12
  rendererWithCallback(options, (result) => {
@@ -38,22 +39,21 @@ function nestedRenderer(rendererWithCallback, conf) {
38
39
  if (!components?.length) {
39
40
  throw new Error(resources_1.default.errors.registry.NESTED_RENDERER_COMPONENTS_IS_NOT_VALID);
40
41
  }
41
- return Promise.all(components.map((component) => {
42
- return renderer({
43
- conf: conf,
44
- headers: {
45
- ...options.headers,
46
- accept: settings_1.default.registry.acceptRenderedHeader
47
- },
48
- ip: component.ip || '',
49
- name: component.name,
50
- parameters: {
51
- ...options.parameters,
52
- ...component.parameters
53
- },
54
- version: component.version || ''
55
- }).catch((err) => new Error(err));
56
- }));
42
+ const limit = (0, pLimit_1.default)(10);
43
+ return Promise.all(components.map((component) => limit(() => renderer({
44
+ conf: conf,
45
+ headers: {
46
+ ...options.headers,
47
+ accept: settings_1.default.registry.acceptRenderedHeader
48
+ },
49
+ ip: component.ip || '',
50
+ name: component.name,
51
+ parameters: {
52
+ ...options.parameters,
53
+ ...component.parameters
54
+ },
55
+ version: component.version || ''
56
+ }).catch((err) => new Error(err)))));
57
57
  }
58
58
  };
59
59
  }
@@ -5,5 +5,5 @@ type ValidationResult = {
5
5
  isValid: false;
6
6
  missing: string[];
7
7
  };
8
- export default function pluginsRequirements(componentRequirements: Record<string, (...args: unknown[]) => unknown> | string[] | null | undefined, registryPlugins: Config['plugins']): ValidationResult;
8
+ export default function pluginsRequirements(componentRequirements: Record<string, (...args: unknown[]) => unknown> | string[] | null | undefined, registryPlugins: Config['plugins'] | ReadonlySet<string>): ValidationResult;
9
9
  export {};
@@ -6,9 +6,11 @@ function pluginsRequirements(componentRequirements, registryPlugins) {
6
6
  const requiredPlugins = Array.isArray(componentRequirements)
7
7
  ? componentRequirements
8
8
  : Object.keys(componentRequirements || {});
9
+ const registryPluginNames = registryPlugins instanceof Set
10
+ ? registryPlugins
11
+ : new Set(Object.keys(registryPlugins || {}));
9
12
  for (const requiredPlugin of requiredPlugins) {
10
- if (!registryPlugins ||
11
- !Object.keys(registryPlugins).includes(requiredPlugin)) {
13
+ if (!registryPluginNames.has(requiredPlugin)) {
12
14
  missing.push(requiredPlugin);
13
15
  }
14
16
  }
@@ -8,13 +8,15 @@ exports.validateNewVersion = validateNewVersion;
8
8
  const semver_1 = __importDefault(require("semver"));
9
9
  const semver_extra_1 = __importDefault(require("semver-extra"));
10
10
  function getAvailableVersion(requestedVersion, availableVersions) {
11
- if (typeof requestedVersion === 'undefined') {
12
- requestedVersion = '';
11
+ if (!requestedVersion) {
12
+ return (semver_1.default.maxSatisfying(availableVersions, '') ||
13
+ semver_extra_1.default.max(availableVersions) ||
14
+ undefined);
13
15
  }
14
- const version = semver_1.default.maxSatisfying(availableVersions, requestedVersion) || undefined;
15
- const max = semver_extra_1.default.max(availableVersions);
16
- const isLatest = requestedVersion === '';
17
- return version || (isLatest && max) || undefined;
16
+ if (availableVersions.includes(requestedVersion)) {
17
+ return requestedVersion;
18
+ }
19
+ return semver_1.default.maxSatisfying(availableVersions, requestedVersion) || undefined;
18
20
  }
19
21
  function validateNewVersion(requestedVersion, availableVersions) {
20
22
  return !availableVersions.includes(requestedVersion);
@@ -14,6 +14,9 @@ const bind = (adapter, options) => {
14
14
  res.conf = options;
15
15
  });
16
16
  adapter.enableRequestTiming((req, res, time) => {
17
+ if (!events_handler_1.default.hasListeners('request')) {
18
+ return;
19
+ }
17
20
  const data = {
18
21
  body: req.body,
19
22
  duration: time,
@@ -4,8 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.default = components;
7
- const async_1 = __importDefault(require("async"));
8
7
  const resources_1 = __importDefault(require("../../resources"));
8
+ const pLimit_1 = __importDefault(require("../../utils/pLimit"));
9
9
  const get_component_1 = __importDefault(require("./helpers/get-component"));
10
10
  function components(conf, repository) {
11
11
  const getComponent = (0, get_component_1.default)(conf, repository);
@@ -57,7 +57,8 @@ function components(conf, repository) {
57
57
  return returnError(errors.join(', '));
58
58
  }
59
59
  }
60
- async_1.default.map(components, (component, callback) => {
60
+ const limit = (0, pLimit_1.default)(10);
61
+ Promise.all(components.map((component) => limit(() => new Promise((resolve) => {
61
62
  getComponent({
62
63
  conf: res.conf,
63
64
  action: component.action,
@@ -65,31 +66,29 @@ function components(conf, repository) {
65
66
  headers: req.headers,
66
67
  ip: req.ip,
67
68
  omitHref: !!req.body.omitHref,
68
- parameters: { ...req.body.parameters, ...component.parameters },
69
+ parameters: {
70
+ ...req.body.parameters,
71
+ ...component.parameters
72
+ },
69
73
  version: component.version
70
- }, (result) => callback(null, result));
71
- },
72
- // @ts-expect-error
73
- (_err, results) => {
74
+ }, resolve);
75
+ })))).then((results) => {
74
76
  try {
75
77
  setHeaders(results, res);
76
78
  setCookies(results, res);
77
- res.status(200).json(results);
79
+ res
80
+ .status(200)
81
+ .json(results.map((result) => result.response.renderMode && !result.headers
82
+ ? { ...result, headers: {} }
83
+ : result));
78
84
  }
79
85
  catch (e) {
80
- // @ts-expect-error I think this will never reach (how can setHeaders throw?)
81
- if (results.code && results.error) {
82
- // @ts-expect-error
83
- res.status(500).json({ code: results.code, error: results.error });
84
- }
85
- else {
86
- res.status(500).json({
87
- code: 'RENDER_ERROR',
88
- error: resources_1.default.errors.registry.RENDER_ERROR(results
89
- .map((x) => `${x.response.name}@${x.response.version}`)
90
- .join(', '), String(e))
91
- });
92
- }
86
+ res.status(500).json({
87
+ code: 'RENDER_ERROR',
88
+ error: resources_1.default.errors.registry.RENDER_ERROR(results
89
+ .map((x) => `${x.response.name}@${x.response.version}`)
90
+ .join(', '), String(e))
91
+ });
93
92
  }
94
93
  });
95
94
  };
@@ -27,6 +27,7 @@ export interface GetComponentResult {
27
27
  error?: unknown;
28
28
  version?: string;
29
29
  html?: string;
30
+ renderMode?: string;
30
31
  requestVersion?: string;
31
32
  name?: string;
32
33
  details?: {
@@ -123,21 +123,53 @@ function getComponent(conf, repository) {
123
123
  refreshInterval: conf.refreshInterval
124
124
  });
125
125
  const convertPlugins = pluginConverter(conf.plugins);
126
+ const customHeadersByConfig = new WeakMap();
127
+ const pluginNamesByConfig = new WeakMap();
128
+ const getCustomHeadersToSkip = (config) => {
129
+ if (!customHeadersByConfig.has(config)) {
130
+ customHeadersByConfig.set(config, config.customHeadersToSkipOnWeakVersion?.length
131
+ ? new Set(config.customHeadersToSkipOnWeakVersion)
132
+ : undefined);
133
+ }
134
+ return customHeadersByConfig.get(config);
135
+ };
136
+ const getRegistryPluginNames = (config) => {
137
+ let names = pluginNamesByConfig.get(config);
138
+ if (!names) {
139
+ names = new Set(Object.keys(config.plugins || {}));
140
+ pluginNamesByConfig.set(config, names);
141
+ }
142
+ return names;
143
+ };
144
+ const inFlight = new Map();
145
+ const singleFlight = (key, operation) => {
146
+ const pending = inFlight.get(key);
147
+ if (pending) {
148
+ return pending;
149
+ }
150
+ const promise = operation().finally(() => {
151
+ inFlight.delete(key);
152
+ });
153
+ inFlight.set(key, promise);
154
+ return promise;
155
+ };
126
156
  const getEnv = async (component) => {
127
157
  const cacheKey = `${component.name}/${component.version}/.env`;
128
158
  const cached = cache.get('file-contents', cacheKey);
129
159
  if (cached)
130
160
  return cached;
131
- const env = component.oc.files.env
132
- ? await repository.getEnv(component.name, component.version)
133
- : {};
134
- cache.set('file-contents', cacheKey, env);
135
- return env;
161
+ return singleFlight(cacheKey, async () => {
162
+ const env = component.oc.files.env
163
+ ? await repository.getEnv(component.name, component.version)
164
+ : {};
165
+ cache.set('file-contents', cacheKey, env);
166
+ return env;
167
+ });
136
168
  };
137
169
  const renderer = async (options, cb) => {
138
170
  const nestedRenderer = (0, nested_renderer_1.default)(renderer, options.conf);
139
171
  const retrievingInfo = (0, get_component_retrieving_info_1.default)(options);
140
- let responseHeaders = {};
172
+ let responseHeaders;
141
173
  const responseCookies = [];
142
174
  const getLanguage = () => {
143
175
  const paramOverride = !!options.parameters && options.parameters['__ocAcceptLanguage'];
@@ -159,11 +191,8 @@ function getComponent(conf, repository) {
159
191
  return cb(result);
160
192
  };
161
193
  let componentCallbackDone = false;
194
+ let callbackTimeout;
162
195
  const conf = options.conf;
163
- const customHeadersToSkipSet = conf.customHeadersToSkipOnWeakVersion?.length
164
- ? new Set(conf.customHeadersToSkipOnWeakVersion)
165
- : undefined;
166
- const acceptLanguage = getLanguage();
167
196
  const requestedComponent = {
168
197
  name: options.name,
169
198
  version: options.version || '',
@@ -196,7 +225,7 @@ function getComponent(conf, repository) {
196
225
  });
197
226
  }
198
227
  // check component requirements are satisfied by registry
199
- const pluginsCompatibility = validator.validatePluginsRequirements(component.oc.plugins, conf.plugins);
228
+ const pluginsCompatibility = validator.validatePluginsRequirements(component.oc.plugins, getRegistryPluginNames(conf));
200
229
  if (!pluginsCompatibility.isValid) {
201
230
  return callback({
202
231
  status: 501,
@@ -249,7 +278,10 @@ function getComponent(conf, repository) {
249
278
  });
250
279
  }
251
280
  const filterCustomHeaders = (headers, requestedVersion, actualVersion) => {
252
- if (!customHeadersToSkipSet || requestedVersion === actualVersion) {
281
+ const customHeadersToSkipSet = getCustomHeadersToSkip(conf);
282
+ if (!headers ||
283
+ !customHeadersToSkipSet ||
284
+ requestedVersion === actualVersion) {
253
285
  return headers;
254
286
  }
255
287
  let filteredHeaders;
@@ -259,28 +291,32 @@ function getComponent(conf, repository) {
259
291
  filteredHeaders[key] = headers[key];
260
292
  }
261
293
  }
262
- return filteredHeaders || {};
294
+ return filteredHeaders;
263
295
  };
264
296
  const returnComponent = async (err, data) => {
265
297
  if (componentCallbackDone) {
266
298
  return;
267
299
  }
268
300
  componentCallbackDone = true;
301
+ if (callbackTimeout) {
302
+ clearTimeout(callbackTimeout);
303
+ callbackTimeout = undefined;
304
+ }
269
305
  const componentHref = urlBuilder.component({
270
306
  name: component.name,
271
307
  version: requestedComponent.version,
272
308
  parameters: params
273
309
  }, conf.baseUrl);
274
310
  const isUnrendered = options.headers.accept === settings_1.default.registry.acceptUnrenderedHeader;
275
- const isValidClientRequest = options.headers['user-agent'] &&
276
- !!options.headers['user-agent'].match('oc-client-');
277
- const supportedTemplates = options.headers['templates']
278
- ? parseTemplatesHeader(options.headers['templates'])
279
- : [];
280
- const isTemplateSupportedByClient = Boolean(isValidClientRequest &&
281
- options.headers['templates'] &&
282
- (supportedTemplates.includes(component.oc.files.template.type) ||
283
- supportedTemplates.includes(templateType)));
311
+ const isValidClientRequest = String(options.headers['user-agent'] || '').includes('oc-client-');
312
+ const templatesHeader = options.headers['templates'];
313
+ let isTemplateSupportedByClient = false;
314
+ if (isUnrendered && isValidClientRequest && templatesHeader) {
315
+ const supportedTemplates = parseTemplatesHeader(templatesHeader);
316
+ isTemplateSupportedByClient =
317
+ supportedTemplates.includes(component.oc.files.template.type) ||
318
+ supportedTemplates.includes(templateType);
319
+ }
284
320
  let renderMode = options.action ? 'unrendered' : 'rendered';
285
321
  if (isUnrendered) {
286
322
  renderMode = 'unrendered';
@@ -356,7 +392,7 @@ function getComponent(conf, repository) {
356
392
  if (renderMode === 'unrendered') {
357
393
  callback({
358
394
  status: 200,
359
- headers: responseHeaders,
395
+ ...(responseHeaders ? { headers: responseHeaders } : {}),
360
396
  response: Object.assign(response, {
361
397
  data: data,
362
398
  template: {
@@ -396,7 +432,7 @@ function getComponent(conf, repository) {
396
432
  }
397
433
  callback({
398
434
  status: 200,
399
- headers: responseHeaders,
435
+ ...(responseHeaders ? { headers: responseHeaders } : {}),
400
436
  response: Object.assign(response, { html })
401
437
  });
402
438
  });
@@ -405,11 +441,22 @@ function getComponent(conf, repository) {
405
441
  returnResult(cached);
406
442
  }
407
443
  else {
408
- (0, universalify_1.fromPromise)(repository.getCompiledView)(component.name, component.version, (_err, templateText) => {
444
+ const loadTemplate = async () => {
445
+ const templateText = await repository.getCompiledView(component.name, component.version);
409
446
  const template = ocTemplate.getCompiledTemplate(templateText, key);
410
447
  cache.set('file-contents', cacheKey, template);
411
- returnResult(template);
412
- });
448
+ return template;
449
+ };
450
+ const templatePromise = conf.hotReloading
451
+ ? loadTemplate()
452
+ : singleFlight(cacheKey, loadTemplate);
453
+ templatePromise.then(returnResult).catch((error) => callback({
454
+ status: 500,
455
+ response: {
456
+ code: 'INTERNAL_SERVER_ERROR',
457
+ error
458
+ }
459
+ }));
413
460
  }
414
461
  }
415
462
  };
@@ -440,9 +487,13 @@ function getComponent(conf, repository) {
440
487
  const cached = cache.get('file-contents', cacheKey);
441
488
  const domain = node_domain_1.default.create();
442
489
  const setEmptyResponse = oc_empty_response_handler_1.default.contextDecorator(returnComponent);
490
+ let parsedAcceptLanguage;
443
491
  const contextObj = {
444
492
  action: options.action,
445
- acceptLanguage: accept_language_parser_1.default.parse(acceptLanguage),
493
+ get acceptLanguage() {
494
+ parsedAcceptLanguage ??= accept_language_parser_1.default.parse(getLanguage());
495
+ return parsedAcceptLanguage;
496
+ },
446
497
  baseUrl: conf.baseUrl,
447
498
  env: { ...conf.env, ...env },
448
499
  params,
@@ -479,7 +530,7 @@ function getComponent(conf, repository) {
479
530
  const setCallbackTimeout = () => {
480
531
  const executionTimeout = conf.executionTimeout;
481
532
  if (executionTimeout) {
482
- setTimeout(() => {
533
+ callbackTimeout = setTimeout(() => {
483
534
  const message = `timeout (${executionTimeout * 1000}ms)`;
484
535
  returnComponent({ message }, undefined);
485
536
  domain.exit();
@@ -490,8 +541,8 @@ function getComponent(conf, repository) {
490
541
  domain.on('error', returnComponent);
491
542
  try {
492
543
  domain.run(() => {
493
- cached(contextObj, returnComponent);
494
544
  setCallbackTimeout();
545
+ cached(contextObj, returnComponent);
495
546
  });
496
547
  }
497
548
  catch (e) {
@@ -499,17 +550,36 @@ function getComponent(conf, repository) {
499
550
  }
500
551
  }
501
552
  else {
502
- (0, universalify_1.fromPromise)(repository.getDataProvider)(component.name, component.version, (err, dataProvider) => {
503
- if (err) {
553
+ const handleError = (err) => {
554
+ if (err.code === 'DATA_RESOLVING_ERROR') {
504
555
  componentCallbackDone = true;
505
556
  return callback({
506
557
  status: 502,
507
558
  response: {
508
- code: 'DATA_RESOLVING_ERROR',
559
+ code: err.code,
509
560
  error: resources_1.default.errors.registry.RESOLVING_ERROR
510
561
  }
511
562
  });
512
563
  }
564
+ if (err.code === 'DEPENDENCY_MISSING_FROM_REGISTRY') {
565
+ componentCallbackDone = true;
566
+ return callback({
567
+ status: 501,
568
+ response: {
569
+ code: err.code,
570
+ error: resources_1.default.errors.registry.DEPENDENCY_NOT_FOUND(err.missing.join(', ')),
571
+ missingDependencies: err.missing
572
+ }
573
+ });
574
+ }
575
+ returnComponent(err, undefined);
576
+ };
577
+ const loadDataProvider = async () => {
578
+ const dataProvider = await repository
579
+ .getDataProvider(component.name, component.version)
580
+ .catch(() => {
581
+ throw { code: 'DATA_RESOLVING_ERROR', missing: [] };
582
+ });
513
583
  const context = {
514
584
  require: (0, require_wrapper_1.default)(conf.dependencies),
515
585
  module: {
@@ -538,40 +608,29 @@ function getComponent(conf, repository) {
538
608
  }
539
609
  }
540
610
  };
541
- const handleError = (err) => {
542
- if (err.code === 'DEPENDENCY_MISSING_FROM_REGISTRY') {
543
- componentCallbackDone = true;
544
- return callback({
545
- status: 501,
546
- response: {
547
- code: err.code,
548
- error: resources_1.default.errors.registry.DEPENDENCY_NOT_FOUND(err.missing.join(', ')),
549
- missingDependencies: err.missing
550
- }
551
- });
552
- }
553
- returnComponent(err, undefined);
554
- };
555
- const options = conf.local
611
+ const vmOptions = conf.local
556
612
  ? {
557
613
  displayErrors: true,
558
614
  filename: dataProvider.filePath
559
615
  }
560
616
  : {};
561
- try {
562
- node_vm_1.default.runInNewContext(dataProvider.content, context, options);
563
- const processData = context.module.exports['data'] || context.exports['data'];
564
- cache.set('file-contents', cacheKey, processData);
565
- domain.on('error', handleError);
566
- domain.run(() => {
567
- processData(contextObj, returnComponent);
568
- setCallbackTimeout();
569
- });
570
- }
571
- catch (err) {
572
- handleError(err);
573
- }
574
- });
617
+ node_vm_1.default.runInNewContext(dataProvider.content, context, vmOptions);
618
+ const processData = context.module.exports['data'] || context.exports['data'];
619
+ cache.set('file-contents', cacheKey, processData);
620
+ return processData;
621
+ };
622
+ const dataProviderPromise = conf.hotReloading
623
+ ? loadDataProvider()
624
+ : singleFlight(cacheKey, loadDataProvider);
625
+ dataProviderPromise
626
+ .then((processData) => {
627
+ domain.on('error', handleError);
628
+ domain.run(() => {
629
+ setCallbackTimeout();
630
+ processData(contextObj, returnComponent);
631
+ });
632
+ })
633
+ .catch(handleError);
575
634
  }
576
635
  });
577
636
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oc",
3
- "version": "0.50.58",
3
+ "version": "0.50.59",
4
4
  "description": "A framework for developing and distributing html components",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -95,7 +95,7 @@
95
95
  "multer": "^2.0.2",
96
96
  "nice-cache": "^0.0.5",
97
97
  "oc-client": "^4.0.3",
98
- "oc-client-browser": "^2.1.11",
98
+ "oc-client-browser": "^2.1.12",
99
99
  "oc-empty-response-handler": "^1.0.2",
100
100
  "oc-get-unix-utc-timestamp": "^1.0.6",
101
101
  "oc-metadata-adapters-utils": "^0.1.1",