@syncbridge/common 0.10.3 → 0.12.0

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.
Files changed (36) hide show
  1. package/classes/base-element.d.ts +1 -1
  2. package/classes/console-logger.d.ts +1 -1
  3. package/classes/console-logger.js +1 -1
  4. package/classes/frame-stream.d.ts +2 -2
  5. package/classes/runnable.d.ts +1 -1
  6. package/classes/sb-error.d.ts +1 -1
  7. package/classes/stack-executor.d.ts +3 -3
  8. package/classes/stack-executor.js +2 -0
  9. package/constants.js +1 -1
  10. package/decorators/component.decorator.d.ts +1 -1
  11. package/decorators/component.decorator.js +3 -1
  12. package/decorators/define-variable.decorator.d.ts +2 -2
  13. package/decorators/define-variable.decorator.js +4 -2
  14. package/decorators/processor-events.decorator.d.ts +1 -1
  15. package/decorators/processor.decorator.d.ts +2 -2
  16. package/decorators/processor.decorator.js +4 -3
  17. package/decorators/use-component.decorator.d.ts +1 -1
  18. package/decorators/use-component.decorator.js +3 -0
  19. package/index.d.ts +1 -1
  20. package/index.js +1 -1
  21. package/models/enums/variable-type.enum.d.ts +1 -0
  22. package/models/enums/variable-type.enum.js +1 -0
  23. package/models-document.js +1 -1
  24. package/package.json +4 -4
  25. package/processor-factory.d.ts +8 -2
  26. package/processor-factory.js +143 -73
  27. package/registry/extension-package.d.ts +1 -1
  28. package/registry/extension-package.js +5 -1
  29. package/registry/extension-registry.d.ts +1 -1
  30. package/registry/extension-registry.js +2 -0
  31. package/utils/decode-profile.js +6 -2
  32. package/utils/materialize-metadata.d.ts +5 -1
  33. package/utils/materialize-metadata.js +9 -9
  34. package/utils/normalize-metadata.js +6 -3
  35. /package/utils/{type-guartds.d.ts → type-guards.d.ts} +0 -0
  36. /package/utils/{type-guartds.js → type-guards.js} +0 -0
@@ -1,4 +1,4 @@
1
- import { ILogger } from '../interfaces/index.js';
1
+ import type { ILogger } from '../interfaces/index.js';
2
2
  import { ServiceStatus } from '../models/index.js';
3
3
  import type { ComponentBase } from './component-base.js';
4
4
  import { Runnable } from './runnable.js';
@@ -1,4 +1,4 @@
1
- import { ILogger } from '../interfaces/index.js';
1
+ import type { ILogger } from '../interfaces/index.js';
2
2
  export declare class ConsoleLogger implements ILogger {
3
3
  level: string;
4
4
  critical(...args: any[]): ILogger;
@@ -21,7 +21,7 @@ export class ConsoleLogger {
21
21
  return this;
22
22
  }
23
23
  trace(...args) {
24
- console.trace(...args);
24
+ console.info(...args);
25
25
  return this;
26
26
  }
27
27
  warn(...args) {
@@ -1,7 +1,7 @@
1
1
  import { Buffer } from 'node:buffer';
2
2
  import { Transform } from 'node:stream';
3
- import { TransformCallback, TransformOptions } from 'stream';
4
- import { StrictOmit } from 'ts-gems';
3
+ import type { TransformCallback, TransformOptions } from 'stream';
4
+ import type { StrictOmit } from 'ts-gems';
5
5
  export declare class FrameStream extends Transform {
6
6
  private _chunks;
7
7
  private _chunkBuffer?;
@@ -1,4 +1,4 @@
1
- import { AsyncEventEmitter, EventMap } from 'node-events-async';
1
+ import { AsyncEventEmitter, type EventMap } from 'node-events-async';
2
2
  import { ServiceStatus } from '../models/index.js';
3
3
  /**
4
4
  *
@@ -1,4 +1,4 @@
1
- import { ErrorIssue } from '@opra/common';
1
+ import type { ErrorIssue } from '@opra/common';
2
2
  export declare class SbError extends Error implements ErrorIssue {
3
3
  readonly cause?: Error;
4
4
  severity: ErrorIssue['severity'];
@@ -1,10 +1,10 @@
1
- import { ErrorIssue } from '@opra/common';
1
+ import type { ErrorIssue } from '@opra/common';
2
2
  type NotPromise<T> = T extends Promise<any> ? never : T;
3
3
  export declare class StackExecutor {
4
4
  stack: string[];
5
5
  issues: StackExecutor.Issue[];
6
- executeAsync(stack: string, fn: () => Promise<any>): Promise<void>;
7
- execute<T>(stack: string, fn: () => NotPromise<T>): void;
6
+ executeAsync(stack: string, fn: () => Promise<any>): Promise<boolean>;
7
+ execute<T>(stack: string, fn: () => NotPromise<T>): boolean;
8
8
  handleError(e: any): void;
9
9
  }
10
10
  export declare namespace StackExecutor {
@@ -14,6 +14,7 @@ export class StackExecutor {
14
14
  finally {
15
15
  this.stack.pop();
16
16
  }
17
+ return !this.issues.find(i => !(i.severity === 'warning' || i.severity === 'info'));
17
18
  }
18
19
  execute(stack, fn) {
19
20
  this.stack.push(stack);
@@ -26,6 +27,7 @@ export class StackExecutor {
26
27
  finally {
27
28
  this.stack.pop();
28
29
  }
30
+ return !this.issues.find(i => !(i.severity === 'warning' || i.severity === 'info'));
29
31
  }
30
32
  handleError(e) {
31
33
  const location = this.stack.join('/');
package/constants.js CHANGED
@@ -1,4 +1,4 @@
1
- export const version = '0.10.3';
1
+ export const version = '0.12.0';
2
2
  export const CLASS_METADATA = Symbol.for('CLASS_METADATA');
3
3
  export const CLASS_TYPE = Symbol.for('CLASS_TYPE');
4
4
  export const VARIABLE_CONTAINER = Symbol.for('VARIABLE_CONTAINER');
@@ -1,5 +1,5 @@
1
1
  import 'reflect-metadata';
2
- import { DeepPartial, StrictOmit, Type } from 'ts-gems';
2
+ import type { DeepPartial, StrictOmit, Type } from 'ts-gems';
3
3
  import { ComponentBase } from '../classes/component-base.js';
4
4
  import { ComponentMetadata } from '../models/index.js';
5
5
  import { UseComponent as _UseComponent } from './use-component.decorator.js';
@@ -2,12 +2,14 @@ import 'reflect-metadata';
2
2
  import path from 'node:path';
3
3
  import { omit } from '@jsopen/objects';
4
4
  import callerCallsite from 'caller-callsite';
5
+ import { ComponentBase } from '../classes/component-base.js';
5
6
  import { CLASS_METADATA, CLASS_TYPE } from '../constants.js';
7
+ import { ComponentMetadata } from '../models/index.js';
6
8
  import { resolvePackageJson } from '../utils/locate-package-json.js';
7
9
  import { defineOwnMetadata, parseNpmAuthor } from './decorator-helpers.js';
8
10
  import { UseComponent as _UseComponent } from './use-component.decorator.js';
9
11
  import { UseVariables as _UseVariables } from './use-variables.decorator.js';
10
- const NAME_PATTERN = /^(.*?)(Component)?$/;
12
+ const NAME_PATTERN = /^([A-Z][A-Za-z0-9_]*?)(Component)?$/;
11
13
  export function Component(options) {
12
14
  const callerFile = callerCallsite()?.getFileName();
13
15
  const pkgjson = callerFile && resolvePackageJson(path.dirname(callerFile));
@@ -1,7 +1,7 @@
1
1
  import 'reflect-metadata';
2
- import { DeepPartial, StrictOmit, Type } from 'ts-gems';
2
+ import type { DeepPartial, StrictOmit, Type } from 'ts-gems';
3
3
  import { VariableMetadata, VariableMetadataRecord } from '../models/index.js';
4
- export declare function DefineVariable(options: DefineVariable.Options): (target: Object, propertyKey: string | symbol) => void;
4
+ export declare function DefineVariable(options?: DefineVariable.Options): (target: Object, propertyKey: string | symbol) => void;
5
5
  type TEnumValue = (string | number)[] | Record<string, string | number>;
6
6
  type TVariable = DeepPartial<VariableMetadataRecord> | Type;
7
7
  export declare namespace DefineVariable {
@@ -1,8 +1,8 @@
1
1
  import 'reflect-metadata';
2
2
  import { deepClone, merge, omitUndefined } from '@jsopen/objects';
3
3
  import { VARIABLE_CONTAINER } from '../constants.js';
4
- import { VariableType, } from '../models/index.js';
5
- export function DefineVariable(options) {
4
+ import { VariableMetadata, VariableMetadataRecord, VariableType, } from '../models/index.js';
5
+ export function DefineVariable(options = {}) {
6
6
  return function (target, propertyKey) {
7
7
  /** c8 ignore next */
8
8
  if (typeof propertyKey !== 'string')
@@ -36,6 +36,8 @@ export function DefineVariable(options) {
36
36
  metadata.type = VariableType.Boolean;
37
37
  else if (designType === Number)
38
38
  metadata.type = VariableType.Number;
39
+ else if (designType === BigInt)
40
+ metadata.type = VariableType.BigInt;
39
41
  else if (typeof designType === 'function' &&
40
42
  Reflect.hasMetadata(VARIABLE_CONTAINER, designType.prototype)) {
41
43
  metadata.type = VariableType.Nested;
@@ -1,5 +1,5 @@
1
1
  import 'reflect-metadata';
2
- import { Type } from 'ts-gems';
2
+ import type { Type } from 'ts-gems';
3
3
  import type { ProcessorBase } from '../classes/processor-base.js';
4
4
  export declare function OnCreateProfile<T extends Type<ProcessorBase>>(): (target: T, propertyKey: string | symbol) => void;
5
5
  export declare function OnUpdateProfile<T extends Type<ProcessorBase>>(): (target: T, propertyKey: string | symbol) => void;
@@ -1,9 +1,9 @@
1
1
  import 'reflect-metadata';
2
- import { DeepPartial, StrictOmit, Type } from 'ts-gems';
2
+ import type { DeepPartial, StrictOmit, Type } from 'ts-gems';
3
3
  import type { ProcessorBase } from '../classes/processor-base.js';
4
4
  import { ProcessorMetadata } from '../models/index.js';
5
5
  import { UseComponent as _UseComponent } from './use-component.decorator.js';
6
- export declare function Processor<T extends ProcessorBase>(options: Processor.Options): (target: Type<T>) => void;
6
+ export declare function Processor<T extends ProcessorBase>(options?: Processor.Options): (target: Type<T>) => void;
7
7
  export declare namespace Processor {
8
8
  /**
9
9
  *
@@ -3,12 +3,13 @@ import path from 'node:path';
3
3
  import { omit } from '@jsopen/objects';
4
4
  import callerCallsite from 'caller-callsite';
5
5
  import { CLASS_METADATA, CLASS_TYPE } from '../constants.js';
6
+ import { ProcessorMetadata } from '../models/index.js';
6
7
  import { resolvePackageJson } from '../utils/locate-package-json.js';
7
8
  import { defineOwnMetadata } from './decorator-helpers.js';
8
9
  import { OnCreateProfile as _OnCreateProfile, OnUpdateProfile as _OnUpdateProfile, } from './processor-events.decorator.js';
9
10
  import { UseComponent as _UseComponent } from './use-component.decorator.js';
10
11
  import { UseVariables as _UseVariables } from './use-variables.decorator.js';
11
- const NAME_PATTERN = /^(.*?)(Processor)?$/;
12
+ const NAME_PATTERN = /^([A-Z][A-Za-z0-9_]*)(Processor)?$/;
12
13
  export function Processor(options) {
13
14
  const callerFile = callerCallsite()?.getFileName();
14
15
  const pkgjson = callerFile && resolvePackageJson(path.dirname(callerFile));
@@ -19,7 +20,7 @@ export function Processor(options) {
19
20
  if (classType && classType !== 'processor')
20
21
  throw new TypeError(`${target.name} already decorated as "${classType}"`);
21
22
  /** Determine class name */
22
- let className = options.className;
23
+ let className = options?.className;
23
24
  if (!className) {
24
25
  const m = NAME_PATTERN.exec(target.name);
25
26
  if (!m)
@@ -38,7 +39,7 @@ export function Processor(options) {
38
39
  uri,
39
40
  displayName: className,
40
41
  version: pkgjson.version,
41
- abstract: !!options.abstract,
42
+ abstract: !!options?.abstract,
42
43
  ...omit(options, ['uri', 'components', 'variables', 'version']),
43
44
  });
44
45
  target.uri = uri;
@@ -1,5 +1,5 @@
1
1
  import 'reflect-metadata';
2
- import { StrictOmit } from 'ts-gems';
2
+ import type { StrictOmit } from 'ts-gems';
3
3
  import { ComponentBase } from '../classes/component-base.js';
4
4
  import { ProcessorBase } from '../classes/processor-base.js';
5
5
  import { ElementComponentMetadata } from '../models/index.js';
@@ -1,6 +1,9 @@
1
1
  import 'reflect-metadata';
2
2
  import { omit } from '@jsopen/objects';
3
+ import { ComponentBase } from '../classes/component-base.js';
4
+ import { ProcessorBase } from '../classes/processor-base.js';
3
5
  import { CLASS_METADATA } from '../constants.js';
6
+ import { ElementComponentMetadata } from '../models/index.js';
4
7
  import { defineOwnMetadata } from './decorator-helpers.js';
5
8
  export function UseComponent(options = {}) {
6
9
  return function (target, propertyKey) {
package/index.d.ts CHANGED
@@ -20,5 +20,5 @@ export * from './registry/extension-registry.js';
20
20
  export * from './utils/decode-profile.js';
21
21
  export * from './utils/materialize-metadata.js';
22
22
  export * from './utils/normalize-metadata.js';
23
- export * from './utils/type-guartds.js';
23
+ export * from './utils/type-guards.js';
24
24
  export * from './utils/uri-to-id.js';
package/index.js CHANGED
@@ -20,5 +20,5 @@ export * from './registry/extension-registry.js';
20
20
  export * from './utils/decode-profile.js';
21
21
  export * from './utils/materialize-metadata.js';
22
22
  export * from './utils/normalize-metadata.js';
23
- export * from './utils/type-guartds.js';
23
+ export * from './utils/type-guards.js';
24
24
  export * from './utils/uri-to-id.js';
@@ -2,6 +2,7 @@ export declare enum VariableType {
2
2
  String = "string",
3
3
  Secret = "secret",
4
4
  Number = "number",
5
+ BigInt = "bigint",
5
6
  Boolean = "boolean",
6
7
  Nested = "nested",
7
8
  Enum = "enum"
@@ -4,6 +4,7 @@ export var VariableType;
4
4
  VariableType["String"] = "string";
5
5
  VariableType["Secret"] = "secret";
6
6
  VariableType["Number"] = "number";
7
+ VariableType["BigInt"] = "bigint";
7
8
  VariableType["Boolean"] = "boolean";
8
9
  VariableType["Nested"] = "nested";
9
10
  VariableType["Enum"] = "enum";
@@ -1,4 +1,4 @@
1
- import { ApiDocumentFactory } from '@opra/common';
1
+ import { ApiDocument, ApiDocumentFactory } from '@opra/common';
2
2
  import { SbError } from './classes/sb-error.js';
3
3
  import * as models from './models/index.js';
4
4
  let doc;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syncbridge/common",
3
- "version": "0.10.3",
3
+ "version": "0.12.0",
4
4
  "description": "SyncBridge Common utilities",
5
5
  "author": "Panates Inc",
6
6
  "license": "MIT",
@@ -10,9 +10,9 @@
10
10
  "node-events-async": "^1.5.2",
11
11
  "caller-callsite": "^6.0.0",
12
12
  "reflect-metadata": "^0.2.2",
13
- "semver": "^7.7.4",
14
- "ts-gems": "^3.11.6",
15
- "valgen": "^6.0.3"
13
+ "semver": "^7.8.0",
14
+ "ts-gems": "^3.12.0",
15
+ "valgen": "^6.1.0"
16
16
  },
17
17
  "peerDependencies": {
18
18
  "@opra/common": ">=1.17.1 <2"
@@ -1,6 +1,6 @@
1
1
  import { ProcessorBase } from './classes/processor-base.js';
2
2
  import { StackExecutor } from './classes/stack-executor.js';
3
- import { ILogger } from './interfaces/index.js';
3
+ import type { ILogger } from './interfaces/index.js';
4
4
  import { Profile } from './models/index.js';
5
5
  export declare namespace ProcessorFactory {
6
6
  const METADATA_KEY: unique symbol;
@@ -11,10 +11,16 @@ export declare namespace ProcessorFactory {
11
11
  }
12
12
  function createProcessor<T extends ProcessorBase>(profile: Profile, options?: ProcessorOptions): Promise<T>;
13
13
  function createProcessorSilent<T extends ProcessorBase>(profile: Profile, options?: ProcessorOptions): Promise<{
14
+ result: true;
14
15
  processor: T;
15
16
  issues: StackExecutor.Issue[];
17
+ } | {
18
+ result: false;
19
+ issues: StackExecutor.Issue[];
16
20
  }>;
17
- function updateProcessor(processor: ProcessorBase, profile: Profile, options?: ProcessorOptions): Promise<{
21
+ function updateProcessor(processor: ProcessorBase, profile: Profile, options?: ProcessorOptions): Promise<void>;
22
+ function updateProcessorSilent(processor: ProcessorBase, profile: Profile, options?: ProcessorOptions): Promise<{
23
+ result: boolean;
18
24
  issues: StackExecutor.Issue[];
19
25
  }>;
20
26
  }
@@ -1,56 +1,91 @@
1
+ import { clone } from '@jsopen/objects';
1
2
  import equal from 'fast-deep-equal';
3
+ import { ComponentBase } from './classes/component-base.js';
4
+ import { ProcessorBase } from './classes/processor-base.js';
2
5
  import { SbError, SbValidationError } from './classes/sb-error.js';
3
6
  import { StackExecutor } from './classes/stack-executor.js';
7
+ import { ElementComponentMetadataRecord, ProcessorMetadata, Profile, ProfileComponentRecord, VariableMetadataRecord, } from './models/index.js';
4
8
  import { initializeModelsDocument } from './models-document.js';
5
9
  import { ExtensionRegistry } from './registry/extension-registry.js';
6
- import { materializeMetadata } from './utils/materialize-metadata.js';
10
+ import { decodeProfile } from './utils/decode-profile.js';
11
+ import { materializeMetadataSilent } from './utils/materialize-metadata.js';
7
12
  export var ProcessorFactory;
8
13
  (function (ProcessorFactory) {
9
14
  ProcessorFactory.METADATA_KEY = Symbol('METADATA');
10
15
  ProcessorFactory.PROFILE_KEY = Symbol('PROFILE');
11
16
  async function createProcessor(profile, options) {
12
- const { processor: out, issues } = await createProcessorSilent(profile, options);
13
- if (issues?.length) {
17
+ const r1 = await createProcessorSilent(profile, options);
18
+ if (!r1.result) {
14
19
  const msg = 'Error while creating processor.\n ' +
15
- issues
20
+ r1.issues
16
21
  .map(issue => `- ${issue.message}. Location: /${issue.location}`)
17
22
  .join('\n ');
18
- issues.forEach(issue => {
23
+ r1.issues.forEach(issue => {
19
24
  if (issue instanceof SbValidationError)
20
25
  delete issue.stack;
21
26
  });
22
27
  throw new SbValidationError(msg, {
23
- issues,
28
+ issues: r1.issues,
24
29
  });
25
30
  }
26
- return out;
31
+ return r1.processor;
27
32
  }
28
33
  ProcessorFactory.createProcessor = createProcessor;
29
34
  async function createProcessorSilent(profile, options) {
30
- await initializeModelsDocument();
31
- const reg = ExtensionRegistry.getProcessor(profile.processorUri, profile.processorVersion);
32
- const processorClass = await reg.getClass();
33
- const processor = new processorClass({
34
- name: profile.displayName,
35
- logger: options?.logger,
36
- values: profile.values || {},
37
- dataDirectory: options?.dataDirectory,
38
- });
39
35
  const ctx = {
40
36
  stackExecutor: new StackExecutor(),
41
- processor,
37
+ processor: undefined,
42
38
  profile,
43
39
  options,
44
- valueUpdates: new Map(),
45
- };
46
- await _configureProcessor(ctx);
47
- return {
48
- processor: processor,
49
- issues: ctx.stackExecutor.issues,
50
40
  };
41
+ try {
42
+ await initializeModelsDocument();
43
+ if (!(await _configureProcessor(ctx))) {
44
+ return {
45
+ result: false,
46
+ issues: ctx.stackExecutor.issues,
47
+ };
48
+ }
49
+ return {
50
+ result: true,
51
+ processor: ctx.processor,
52
+ issues: ctx.stackExecutor.issues,
53
+ };
54
+ }
55
+ catch (error) {
56
+ return {
57
+ result: false,
58
+ issues: [
59
+ ...ctx.stackExecutor.issues,
60
+ {
61
+ message: error.message,
62
+ type: 'error',
63
+ severity: 'error',
64
+ stack: error.stack,
65
+ },
66
+ ],
67
+ };
68
+ }
51
69
  }
52
70
  ProcessorFactory.createProcessorSilent = createProcessorSilent;
53
71
  async function updateProcessor(processor, profile, options) {
72
+ const r1 = await updateProcessorSilent(processor, profile, options);
73
+ if (!r1.result) {
74
+ const msg = 'Error while updating processor.\n ' +
75
+ r1.issues
76
+ .map(issue => `- ${issue.message}. Location: /${issue.location}`)
77
+ .join('\n ');
78
+ r1.issues.forEach(issue => {
79
+ if (issue instanceof SbValidationError)
80
+ delete issue.stack;
81
+ });
82
+ throw new SbValidationError(msg, {
83
+ issues: r1.issues,
84
+ });
85
+ }
86
+ }
87
+ ProcessorFactory.updateProcessor = updateProcessor;
88
+ async function updateProcessorSilent(processor, profile, options) {
54
89
  if (options?.logger)
55
90
  processor.logger = options.logger;
56
91
  if (options?.dataDirectory)
@@ -62,47 +97,82 @@ export var ProcessorFactory;
62
97
  options,
63
98
  valueUpdates: new Map(),
64
99
  };
65
- await _configureProcessor(ctx);
100
+ if (!(await _configureProcessor(ctx))) {
101
+ return {
102
+ result: false,
103
+ issues: ctx.stackExecutor.issues,
104
+ };
105
+ }
66
106
  const signalUpdates = async (obj) => {
67
107
  if (obj.components) {
68
108
  for (const component of Object.values(obj.components)) {
69
109
  await signalUpdates(component);
70
110
  }
71
111
  }
72
- const properties = ctx.valueUpdates.get(obj);
112
+ const properties = ctx.valueUpdates?.get(obj);
73
113
  if (properties?.length) {
74
114
  await obj.emitAsyncSafe('values-updated', properties);
75
115
  }
76
116
  };
77
117
  await signalUpdates(processor);
78
118
  return {
119
+ result: true,
79
120
  issues: ctx.stackExecutor.issues,
80
121
  };
81
122
  }
82
- ProcessorFactory.updateProcessor = updateProcessor;
123
+ ProcessorFactory.updateProcessorSilent = updateProcessorSilent;
83
124
  async function _configureProcessor(ctx) {
84
- const { processor, profile } = ctx;
85
- const newMetadata = materializeMetadata(profile);
125
+ const r1 = materializeMetadataSilent(ctx.profile);
126
+ if (!r1.result) {
127
+ ctx.stackExecutor.issues.push(...r1.issues);
128
+ return false;
129
+ }
130
+ /* Decode profile */
131
+ const profile = decodeProfile(r1.metadata, ctx.profile);
132
+ ctx.profile = profile;
133
+ const oldMetadata = ctx.processor?.[ProcessorFactory.METADATA_KEY];
134
+ const oldProfile = ctx.processor?.[ProcessorFactory.PROFILE_KEY];
135
+ if (!ctx.processor) {
136
+ /* Create new processor instance */
137
+ const reg = ExtensionRegistry.getProcessor(profile.processorUri, profile.processorVersion);
138
+ const processorClass = await reg.getClass();
139
+ /* Create processor instance */
140
+ ctx.processor = new processorClass({
141
+ name: profile.displayName,
142
+ logger: ctx.options?.logger,
143
+ values: profile.values ? clone(profile.values) : {},
144
+ dataDirectory: ctx.options?.dataDirectory,
145
+ });
146
+ }
147
+ else {
148
+ /* Update values */
149
+ if (!ctx.stackExecutor.execute('values', () => {
150
+ _patchValues(ctx, ctx.processor, ctx.processor.values, '', profile.values, r1.metadata.variables || {}, oldProfile?.values, oldMetadata.variables);
151
+ })) {
152
+ return false;
153
+ }
154
+ }
86
155
  const cmpCtx = {
87
156
  ...ctx,
88
- owner: processor,
157
+ owner: ctx.processor,
89
158
  curPath: '',
90
- newMetadataComponents: newMetadata.components,
159
+ newMetadataComponents: r1.metadata.components,
91
160
  newProfileComponents: profile.components,
92
- oldMetadataComponents: processor[ProcessorFactory.METADATA_KEY]?.components,
93
- oldProfileComponents: processor[ProcessorFactory.PROFILE_KEY]?.components,
161
+ oldMetadataComponents: oldMetadata?.components,
162
+ oldProfileComponents: oldProfile?.components,
94
163
  };
95
- _validateComponents(cmpCtx);
96
- await _configureComponents(cmpCtx);
97
- processor[ProcessorFactory.METADATA_KEY] = newMetadata;
98
- processor[ProcessorFactory.PROFILE_KEY] = profile;
164
+ if (!(_validateComponents(cmpCtx) && (await _configureComponents(cmpCtx)))) {
165
+ return false;
166
+ }
167
+ ctx.processor[ProcessorFactory.METADATA_KEY] = r1.metadata;
168
+ ctx.processor[ProcessorFactory.PROFILE_KEY] = profile;
169
+ return true;
99
170
  }
100
171
  function _validateComponents(ctx) {
101
- const { newMetadataComponents, newProfileComponents, oldMetadataComponents, oldProfileComponents, curPath, owner, stackExecutor, processor, } = ctx;
172
+ const { newMetadataComponents, newProfileComponents, oldMetadataComponents, oldProfileComponents, curPath, owner, stackExecutor, } = ctx;
102
173
  if (!newMetadataComponents)
103
- return;
104
- // Stack: components
105
- stackExecutor.execute('components', () => {
174
+ return true;
175
+ return stackExecutor.execute('components', () => {
106
176
  for (const [key, newChildMetadata] of Object.entries(newMetadataComponents)) {
107
177
  // Stack: components/componentName
108
178
  stackExecutor.execute(key, () => {
@@ -111,10 +181,9 @@ export var ProcessorFactory;
111
181
  const newChildProfile = newProfileComponents[key];
112
182
  const componentPath = curPath ? curPath + '/' + key : key;
113
183
  const componentInstance = owner.components?.[key];
114
- if (processor.stopped &&
115
- oldChildProfile?.uri &&
184
+ if (oldChildProfile?.uri &&
116
185
  oldChildProfile?.uri !== newChildProfile.uri)
117
- throw new SbError('Cannot change component class while processor running. You should stop it first.');
186
+ throw new SbError(`You should not change uri of the component (${componentPath})`);
118
187
  /** Validate sub-components */
119
188
  if (newChildMetadata.components && componentInstance) {
120
189
  _validateComponents({
@@ -134,10 +203,10 @@ export var ProcessorFactory;
134
203
  async function _configureComponents(ctx) {
135
204
  const { newMetadataComponents, newProfileComponents, oldMetadataComponents, oldProfileComponents, curPath, owner, stackExecutor, processor, } = ctx;
136
205
  if (!newMetadataComponents)
137
- return;
206
+ return true;
138
207
  owner.components = owner.components || {};
139
208
  // Stack: components
140
- await stackExecutor.executeAsync('components', async () => {
209
+ return await stackExecutor.executeAsync('components', async () => {
141
210
  for (const [key, newChildMetadata] of Object.entries(newMetadataComponents)) {
142
211
  // Stack: components/componentName
143
212
  await stackExecutor.executeAsync(key, async () => {
@@ -150,17 +219,18 @@ export var ProcessorFactory;
150
219
  const newChildProfile = newProfileComponents[key];
151
220
  const componentPath = curPath ? curPath + '/' + key : key;
152
221
  let componentInstance = owner.components[key];
153
- /** Create the component only if the owner stopped */ // todo implement hotplug components
154
- if (owner.stopped) {
222
+ /** Create the component */
223
+ if (!componentInstance) {
155
224
  const compReg = ExtensionRegistry.getComponent(newChildMetadata.classUri);
156
225
  /** Create the component instance */
157
226
  const compClass = await compReg.getClass();
227
+ const values = { ...newChildProfile.values };
158
228
  componentInstance = new compClass({
159
229
  processor: processor,
160
230
  parent: owner,
161
231
  name: key,
162
232
  path: componentPath,
163
- values: newChildProfile.values || {},
233
+ values,
164
234
  });
165
235
  owner.components[key] = componentInstance;
166
236
  if (newChildMetadata.propertyKey)
@@ -168,30 +238,7 @@ export var ProcessorFactory;
168
238
  }
169
239
  else {
170
240
  componentInstance.values = {};
171
- const patchValues = (target, valPath, newValues, newVariables, oldValues, oldVariables) => {
172
- if (oldValues)
173
- Object.assign(target, oldValues);
174
- const updatedValues = ctx.valueUpdates.get(componentInstance) || [];
175
- ctx.valueUpdates.set(componentInstance, updatedValues);
176
- if (newVariables) {
177
- for (const [varKey, varMeta] of Object.entries(newVariables)) {
178
- const keyPath = valPath ? valPath + '.' + varKey : varKey;
179
- /** Update only hotplug variables */
180
- if (varMeta?.hotPlug !== true)
181
- continue;
182
- if (varMeta.type === 'nested') {
183
- target[varKey] = {};
184
- patchValues(target[varKey], keyPath, newValues[varKey], newVariables[varKey]?.variables || {}, oldValues?.[varKey], oldVariables?.[varKey]?.variables);
185
- continue;
186
- }
187
- if (!equal(target[varKey], newValues[varKey])) {
188
- updatedValues.push(keyPath);
189
- target[varKey] = newValues[varKey];
190
- }
191
- }
192
- }
193
- };
194
- patchValues(componentInstance.values, '', newChildProfile.values || {}, newChildMetadata.variables || {}, oldChildProfile?.values, oldChildMetadata?.variables);
241
+ _patchValues(ctx, componentInstance, componentInstance.values, '', newChildProfile.values || {}, newChildMetadata.variables || {}, oldChildProfile?.values, oldChildMetadata?.variables);
195
242
  }
196
243
  /** Create the child logger */
197
244
  componentInstance.logger = owner.logger?.child({
@@ -201,7 +248,7 @@ export var ProcessorFactory;
201
248
  componentInstance.logger.level =
202
249
  newChildProfile.settings?.logs?.level;
203
250
  }
204
- /** Initialize sub components */
251
+ /** Initialize sub-components */
205
252
  if (newChildMetadata.components) {
206
253
  await _configureComponents({
207
254
  ...ctx,
@@ -218,4 +265,27 @@ export var ProcessorFactory;
218
265
  }
219
266
  });
220
267
  }
268
+ function _patchValues(ctx, instance, target, valPath, newValues, newVariables, oldValues, oldVariables) {
269
+ if (oldValues)
270
+ Object.assign(target, oldValues);
271
+ const updatedValues = ctx.valueUpdates?.get(instance) || [];
272
+ ctx.valueUpdates?.set(instance, updatedValues);
273
+ if (newVariables) {
274
+ for (const [varKey, varMeta] of Object.entries(newVariables)) {
275
+ const keyPath = valPath ? valPath + '.' + varKey : varKey;
276
+ /** Update only hotplug variables */
277
+ if (varMeta?.hotPlug !== true)
278
+ continue;
279
+ if (varMeta.type === 'nested') {
280
+ target[varKey] = {};
281
+ _patchValues(ctx, instance, target[varKey], keyPath, newValues[varKey], newVariables[varKey]?.variables || {}, oldValues?.[varKey], oldVariables?.[varKey]?.variables);
282
+ continue;
283
+ }
284
+ if (!equal(target[varKey], newValues[varKey])) {
285
+ updatedValues.push(keyPath);
286
+ target[varKey] = newValues[varKey];
287
+ }
288
+ }
289
+ }
290
+ }
221
291
  })(ProcessorFactory || (ProcessorFactory = {}));
@@ -1,5 +1,5 @@
1
1
  import 'reflect-metadata';
2
- import { Type } from 'ts-gems';
2
+ import type { Type } from 'ts-gems';
3
3
  import { BaseElement } from '../classes/base-element.js';
4
4
  import { ComponentBase } from '../classes/component-base.js';
5
5
  import { ProcessorBase } from '../classes/processor-base.js';
@@ -1,6 +1,10 @@
1
1
  import 'reflect-metadata';
2
+ import { BaseElement } from '../classes/base-element.js';
3
+ import { ComponentBase } from '../classes/component-base.js';
4
+ import { ProcessorBase } from '../classes/processor-base.js';
2
5
  import { SbError } from '../classes/sb-error.js';
3
- import { isComponentBase, isProcessorBase } from '../utils/type-guartds.js';
6
+ import { ComponentMetadata, ElementMetadata, ProcessorMetadata, } from '../models/index.js';
7
+ import { isComponentBase, isProcessorBase } from '../utils/type-guards.js';
4
8
  /**
5
9
  *
6
10
  */
@@ -1,6 +1,6 @@
1
1
  import { ResponsiveMap } from '@opra/common';
2
2
  import { AsyncEventEmitter } from 'node-events-async';
3
- import { Type } from 'ts-gems';
3
+ import type { Type } from 'ts-gems';
4
4
  import { ComponentBase } from '../classes/component-base.js';
5
5
  import { ProcessorBase } from '../classes/processor-base.js';
6
6
  import { ComponentExtension, ExtensionPackage, ProcessorExtension } from './extension-package.js';
@@ -5,6 +5,8 @@ import { updateErrorMessage } from '@jsopen/objects';
5
5
  import { ResponsiveMap } from '@opra/common';
6
6
  import { AsyncEventEmitter } from 'node-events-async';
7
7
  import semver from 'semver';
8
+ import { ComponentBase } from '../classes/component-base.js';
9
+ import { ProcessorBase } from '../classes/processor-base.js';
8
10
  import { SbError } from '../classes/sb-error.js';
9
11
  import { CLASS_METADATA, CLASS_TYPE } from '../constants.js';
10
12
  import { locatePackageJson } from '../utils/locate-package-json.js';
@@ -1,7 +1,7 @@
1
- import { isAny, isBase64, isBoolean, isDateString, isEmail, isHex, isNumber, isString, isTime, isURL, validator, vg, } from 'valgen';
1
+ import { isAny, isBase64, isBigint, isBoolean, isDateString, isEmail, isHex, isNumber, isString, isTime, isURL, validator, vg, } from 'valgen';
2
2
  import { SbValidationError } from '../classes/sb-error.js';
3
3
  import { StackExecutor } from '../classes/stack-executor.js';
4
- import { Profile, VariableType, } from '../models/index.js';
4
+ import { ElementComponentMetadata, ProcessorMetadata, Profile, ProfileComponent, VariableMetadataRecord, VariableType, } from '../models/index.js';
5
5
  import { getModelsDocument } from '../models-document.js';
6
6
  import { secretDecryptor, secretEncryptor } from './encrypt-helpers.js';
7
7
  /**
@@ -179,6 +179,10 @@ function _decodeVariables(stackExecutor, codec, metadata, profile, options) {
179
179
  fns.push(isNumber);
180
180
  break;
181
181
  }
182
+ case VariableType.BigInt: {
183
+ fns.push(isBigint);
184
+ break;
185
+ }
182
186
  case VariableType.Boolean: {
183
187
  fns.push(isBoolean);
184
188
  break;
@@ -8,6 +8,10 @@ export declare function materializeMetadata(profile: Profile, returnUndefinedCom
8
8
  *
9
9
  */
10
10
  export declare function materializeMetadataSilent(profile: Profile, returnUndefinedComponentsAsAbstract?: boolean): {
11
+ result: true;
11
12
  metadata: ProcessorMetadata;
12
- issues?: StackExecutor.Issue[];
13
+ issues: StackExecutor.Issue[];
14
+ } | {
15
+ result: false;
16
+ issues: StackExecutor.Issue[];
13
17
  };
@@ -1,28 +1,28 @@
1
1
  import { clone, merge, omit, omitUndefined } from '@jsopen/objects';
2
2
  import { SbValidationError } from '../classes/sb-error.js';
3
3
  import { StackExecutor } from '../classes/stack-executor.js';
4
- import { VariableType, } from '../models/index.js';
4
+ import { ElementComponentMetadata, ElementComponentMetadataRecord, ProcessorMetadata, Profile, ProfileComponent, VariableMetadata, VariableMetadataRecord, VariableType, } from '../models/index.js';
5
5
  import { ExtensionRegistry } from '../registry/extension-registry.js';
6
6
  /**
7
7
  * Materializes metadata from profile.
8
8
  */
9
9
  export function materializeMetadata(profile, returnUndefinedComponentsAsAbstract) {
10
- const { metadata, issues } = materializeMetadataSilent(profile, returnUndefinedComponentsAsAbstract);
11
- if (issues?.length) {
10
+ const r = materializeMetadataSilent(profile, returnUndefinedComponentsAsAbstract);
11
+ if (!r.result) {
12
12
  const msg = 'Worker profile validation error.\n ' +
13
- issues
13
+ r.issues
14
14
  .map(issue => `- ${issue.message}. Location: /${issue.location}`)
15
15
  .join('\n ');
16
- issues.forEach(issue => {
16
+ r.issues.forEach(issue => {
17
17
  if (issue instanceof SbValidationError)
18
18
  delete issue.stack;
19
19
  });
20
20
  throw new SbValidationError(msg, {
21
21
  workerId: profile.id,
22
- issues,
22
+ issues: r.issues,
23
23
  });
24
24
  }
25
- return metadata;
25
+ return r.metadata;
26
26
  }
27
27
  /**
28
28
  *
@@ -48,8 +48,8 @@ export function materializeMetadataSilent(profile, returnUndefinedComponentsAsAb
48
48
  });
49
49
  }
50
50
  if (stackExecutor.issues?.length)
51
- return { metadata, issues: stackExecutor.issues };
52
- return { metadata };
51
+ return { result: false, issues: stackExecutor.issues };
52
+ return { result: true, metadata, issues: stackExecutor.issues };
53
53
  }
54
54
  /**
55
55
  *
@@ -1,6 +1,7 @@
1
1
  import { deepClone, merge } from '@jsopen/objects';
2
2
  import { SbValidationError } from '../classes/sb-error.js';
3
- import { ComponentMetadata, ProcessorMetadata, } from '../models/index.js';
3
+ import { StackExecutor } from '../classes/stack-executor.js';
4
+ import { ComponentMetadata, ElementComponentMetadataRecord, ProcessorMetadata, VariableMetadataRecord, } from '../models/index.js';
4
5
  import { initializeModelsDocument } from '../models-document.js';
5
6
  import { resolvePromisesDeep } from './resolve-promises.js';
6
7
  export async function normalizeProcessorMetadata(metadata) {
@@ -38,7 +39,8 @@ export async function normalizeProcessorMetadataSilent(metadata) {
38
39
  cloned.variables = normalizeVariables(cloned.variables);
39
40
  cloned.components = normalizeComponents(cloned.components);
40
41
  const { value, errors } = decoder.silent(cloned);
41
- merge(value, metadata, { keepExisting: true, deep: 'full' });
42
+ if (value)
43
+ merge(value, metadata, { keepExisting: true, deep: 'full' });
42
44
  return {
43
45
  metadata: value || cloned,
44
46
  issues: errors?.map(x => ({
@@ -83,7 +85,8 @@ export async function normalizeComponentMetadataSilent(metadata) {
83
85
  cloned.variables = normalizeVariables(cloned.variables);
84
86
  cloned.components = normalizeComponents(cloned.components);
85
87
  const { value, errors } = decoder.silent(cloned);
86
- merge(value, metadata, { keepExisting: true, deep: 'full' });
88
+ if (value)
89
+ merge(value, metadata, { keepExisting: true, deep: 'full' });
87
90
  return {
88
91
  metadata: value || cloned,
89
92
  issues: errors?.map(x => ({
File without changes
File without changes