@syncbridge/common 0.11.0 → 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.
- package/classes/stack-executor.d.ts +2 -2
- package/classes/stack-executor.js +2 -0
- package/constants.js +1 -1
- package/decorators/component.decorator.js +1 -1
- package/decorators/define-variable.decorator.d.ts +1 -1
- package/decorators/define-variable.decorator.js +3 -1
- package/decorators/processor.decorator.d.ts +1 -1
- package/decorators/processor.decorator.js +3 -3
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/package.json +1 -1
- package/processor-factory.d.ts +7 -1
- package/processor-factory.js +141 -74
- package/registry/extension-package.js +1 -1
- package/utils/materialize-metadata.d.ts +5 -1
- package/utils/materialize-metadata.js +8 -8
- package/utils/normalize-metadata.js +4 -2
- /package/utils/{type-guartds.d.ts → type-guards.d.ts} +0 -0
- /package/utils/{type-guartds.js → type-guards.js} +0 -0
|
@@ -3,8 +3,8 @@ 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<
|
|
7
|
-
execute<T>(stack: string, fn: () => NotPromise<T>):
|
|
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
|
@@ -9,7 +9,7 @@ import { resolvePackageJson } from '../utils/locate-package-json.js';
|
|
|
9
9
|
import { defineOwnMetadata, parseNpmAuthor } from './decorator-helpers.js';
|
|
10
10
|
import { UseComponent as _UseComponent } from './use-component.decorator.js';
|
|
11
11
|
import { UseVariables as _UseVariables } from './use-variables.decorator.js';
|
|
12
|
-
const NAME_PATTERN = /^(
|
|
12
|
+
const NAME_PATTERN = /^([A-Z][A-Za-z0-9_]*?)(Component)?$/;
|
|
13
13
|
export function Component(options) {
|
|
14
14
|
const callerFile = callerCallsite()?.getFileName();
|
|
15
15
|
const pkgjson = callerFile && resolvePackageJson(path.dirname(callerFile));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
2
|
import type { DeepPartial, StrictOmit, Type } from 'ts-gems';
|
|
3
3
|
import { VariableMetadata, VariableMetadataRecord } from '../models/index.js';
|
|
4
|
-
export declare function DefineVariable(options
|
|
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 {
|
|
@@ -2,7 +2,7 @@ import 'reflect-metadata';
|
|
|
2
2
|
import { deepClone, merge, omitUndefined } from '@jsopen/objects';
|
|
3
3
|
import { VARIABLE_CONTAINER } from '../constants.js';
|
|
4
4
|
import { VariableMetadata, VariableMetadataRecord, VariableType, } from '../models/index.js';
|
|
5
|
-
export function DefineVariable(options) {
|
|
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;
|
|
@@ -3,7 +3,7 @@ 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
|
|
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
|
*
|
|
@@ -9,7 +9,7 @@ import { defineOwnMetadata } from './decorator-helpers.js';
|
|
|
9
9
|
import { OnCreateProfile as _OnCreateProfile, OnUpdateProfile as _OnUpdateProfile, } from './processor-events.decorator.js';
|
|
10
10
|
import { UseComponent as _UseComponent } from './use-component.decorator.js';
|
|
11
11
|
import { UseVariables as _UseVariables } from './use-variables.decorator.js';
|
|
12
|
-
const NAME_PATTERN = /^(
|
|
12
|
+
const NAME_PATTERN = /^([A-Z][A-Za-z0-9_]*)(Processor)?$/;
|
|
13
13
|
export function Processor(options) {
|
|
14
14
|
const callerFile = callerCallsite()?.getFileName();
|
|
15
15
|
const pkgjson = callerFile && resolvePackageJson(path.dirname(callerFile));
|
|
@@ -20,7 +20,7 @@ export function Processor(options) {
|
|
|
20
20
|
if (classType && classType !== 'processor')
|
|
21
21
|
throw new TypeError(`${target.name} already decorated as "${classType}"`);
|
|
22
22
|
/** Determine class name */
|
|
23
|
-
let className = options
|
|
23
|
+
let className = options?.className;
|
|
24
24
|
if (!className) {
|
|
25
25
|
const m = NAME_PATTERN.exec(target.name);
|
|
26
26
|
if (!m)
|
|
@@ -39,7 +39,7 @@ export function Processor(options) {
|
|
|
39
39
|
uri,
|
|
40
40
|
displayName: className,
|
|
41
41
|
version: pkgjson.version,
|
|
42
|
-
abstract: !!options
|
|
42
|
+
abstract: !!options?.abstract,
|
|
43
43
|
...omit(options, ['uri', 'components', 'variables', 'version']),
|
|
44
44
|
});
|
|
45
45
|
target.uri = uri;
|
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-
|
|
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-
|
|
23
|
+
export * from './utils/type-guards.js';
|
|
24
24
|
export * from './utils/uri-to-id.js';
|
package/package.json
CHANGED
package/processor-factory.d.ts
CHANGED
|
@@ -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
|
}
|
package/processor-factory.js
CHANGED
|
@@ -1,59 +1,91 @@
|
|
|
1
|
+
import { clone } from '@jsopen/objects';
|
|
1
2
|
import equal from 'fast-deep-equal';
|
|
2
3
|
import { ComponentBase } from './classes/component-base.js';
|
|
3
4
|
import { ProcessorBase } from './classes/processor-base.js';
|
|
4
5
|
import { SbError, SbValidationError } from './classes/sb-error.js';
|
|
5
6
|
import { StackExecutor } from './classes/stack-executor.js';
|
|
6
|
-
import { ElementComponentMetadataRecord, Profile, ProfileComponentRecord, VariableMetadataRecord, } from './models/index.js';
|
|
7
|
+
import { ElementComponentMetadataRecord, ProcessorMetadata, Profile, ProfileComponentRecord, VariableMetadataRecord, } from './models/index.js';
|
|
7
8
|
import { initializeModelsDocument } from './models-document.js';
|
|
8
9
|
import { ExtensionRegistry } from './registry/extension-registry.js';
|
|
9
|
-
import {
|
|
10
|
+
import { decodeProfile } from './utils/decode-profile.js';
|
|
11
|
+
import { materializeMetadataSilent } from './utils/materialize-metadata.js';
|
|
10
12
|
export var ProcessorFactory;
|
|
11
13
|
(function (ProcessorFactory) {
|
|
12
14
|
ProcessorFactory.METADATA_KEY = Symbol('METADATA');
|
|
13
15
|
ProcessorFactory.PROFILE_KEY = Symbol('PROFILE');
|
|
14
16
|
async function createProcessor(profile, options) {
|
|
15
|
-
const
|
|
16
|
-
if (
|
|
17
|
+
const r1 = await createProcessorSilent(profile, options);
|
|
18
|
+
if (!r1.result) {
|
|
17
19
|
const msg = 'Error while creating processor.\n ' +
|
|
18
|
-
issues
|
|
20
|
+
r1.issues
|
|
19
21
|
.map(issue => `- ${issue.message}. Location: /${issue.location}`)
|
|
20
22
|
.join('\n ');
|
|
21
|
-
issues.forEach(issue => {
|
|
23
|
+
r1.issues.forEach(issue => {
|
|
22
24
|
if (issue instanceof SbValidationError)
|
|
23
25
|
delete issue.stack;
|
|
24
26
|
});
|
|
25
27
|
throw new SbValidationError(msg, {
|
|
26
|
-
issues,
|
|
28
|
+
issues: r1.issues,
|
|
27
29
|
});
|
|
28
30
|
}
|
|
29
|
-
return
|
|
31
|
+
return r1.processor;
|
|
30
32
|
}
|
|
31
33
|
ProcessorFactory.createProcessor = createProcessor;
|
|
32
34
|
async function createProcessorSilent(profile, options) {
|
|
33
|
-
await initializeModelsDocument();
|
|
34
|
-
const reg = ExtensionRegistry.getProcessor(profile.processorUri, profile.processorVersion);
|
|
35
|
-
const processorClass = await reg.getClass();
|
|
36
|
-
const processor = new processorClass({
|
|
37
|
-
name: profile.displayName,
|
|
38
|
-
logger: options?.logger,
|
|
39
|
-
values: profile.values || {},
|
|
40
|
-
dataDirectory: options?.dataDirectory,
|
|
41
|
-
});
|
|
42
35
|
const ctx = {
|
|
43
36
|
stackExecutor: new StackExecutor(),
|
|
44
|
-
processor,
|
|
37
|
+
processor: undefined,
|
|
45
38
|
profile,
|
|
46
39
|
options,
|
|
47
|
-
valueUpdates: new Map(),
|
|
48
|
-
};
|
|
49
|
-
await _configureProcessor(ctx);
|
|
50
|
-
return {
|
|
51
|
-
processor: processor,
|
|
52
|
-
issues: ctx.stackExecutor.issues,
|
|
53
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
|
+
}
|
|
54
69
|
}
|
|
55
70
|
ProcessorFactory.createProcessorSilent = createProcessorSilent;
|
|
56
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) {
|
|
57
89
|
if (options?.logger)
|
|
58
90
|
processor.logger = options.logger;
|
|
59
91
|
if (options?.dataDirectory)
|
|
@@ -65,47 +97,82 @@ export var ProcessorFactory;
|
|
|
65
97
|
options,
|
|
66
98
|
valueUpdates: new Map(),
|
|
67
99
|
};
|
|
68
|
-
await _configureProcessor(ctx)
|
|
100
|
+
if (!(await _configureProcessor(ctx))) {
|
|
101
|
+
return {
|
|
102
|
+
result: false,
|
|
103
|
+
issues: ctx.stackExecutor.issues,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
69
106
|
const signalUpdates = async (obj) => {
|
|
70
107
|
if (obj.components) {
|
|
71
108
|
for (const component of Object.values(obj.components)) {
|
|
72
109
|
await signalUpdates(component);
|
|
73
110
|
}
|
|
74
111
|
}
|
|
75
|
-
const properties = ctx.valueUpdates
|
|
112
|
+
const properties = ctx.valueUpdates?.get(obj);
|
|
76
113
|
if (properties?.length) {
|
|
77
114
|
await obj.emitAsyncSafe('values-updated', properties);
|
|
78
115
|
}
|
|
79
116
|
};
|
|
80
117
|
await signalUpdates(processor);
|
|
81
118
|
return {
|
|
119
|
+
result: true,
|
|
82
120
|
issues: ctx.stackExecutor.issues,
|
|
83
121
|
};
|
|
84
122
|
}
|
|
85
|
-
ProcessorFactory.
|
|
123
|
+
ProcessorFactory.updateProcessorSilent = updateProcessorSilent;
|
|
86
124
|
async function _configureProcessor(ctx) {
|
|
87
|
-
const
|
|
88
|
-
|
|
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
|
+
}
|
|
89
155
|
const cmpCtx = {
|
|
90
156
|
...ctx,
|
|
91
|
-
owner: processor,
|
|
157
|
+
owner: ctx.processor,
|
|
92
158
|
curPath: '',
|
|
93
|
-
newMetadataComponents:
|
|
159
|
+
newMetadataComponents: r1.metadata.components,
|
|
94
160
|
newProfileComponents: profile.components,
|
|
95
|
-
oldMetadataComponents:
|
|
96
|
-
oldProfileComponents:
|
|
161
|
+
oldMetadataComponents: oldMetadata?.components,
|
|
162
|
+
oldProfileComponents: oldProfile?.components,
|
|
97
163
|
};
|
|
98
|
-
_validateComponents(cmpCtx)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
processor[ProcessorFactory.
|
|
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;
|
|
102
170
|
}
|
|
103
171
|
function _validateComponents(ctx) {
|
|
104
|
-
const { newMetadataComponents, newProfileComponents, oldMetadataComponents, oldProfileComponents, curPath, owner, stackExecutor,
|
|
172
|
+
const { newMetadataComponents, newProfileComponents, oldMetadataComponents, oldProfileComponents, curPath, owner, stackExecutor, } = ctx;
|
|
105
173
|
if (!newMetadataComponents)
|
|
106
|
-
return;
|
|
107
|
-
|
|
108
|
-
stackExecutor.execute('components', () => {
|
|
174
|
+
return true;
|
|
175
|
+
return stackExecutor.execute('components', () => {
|
|
109
176
|
for (const [key, newChildMetadata] of Object.entries(newMetadataComponents)) {
|
|
110
177
|
// Stack: components/componentName
|
|
111
178
|
stackExecutor.execute(key, () => {
|
|
@@ -114,10 +181,9 @@ export var ProcessorFactory;
|
|
|
114
181
|
const newChildProfile = newProfileComponents[key];
|
|
115
182
|
const componentPath = curPath ? curPath + '/' + key : key;
|
|
116
183
|
const componentInstance = owner.components?.[key];
|
|
117
|
-
if (
|
|
118
|
-
oldChildProfile?.uri &&
|
|
184
|
+
if (oldChildProfile?.uri &&
|
|
119
185
|
oldChildProfile?.uri !== newChildProfile.uri)
|
|
120
|
-
throw new SbError(
|
|
186
|
+
throw new SbError(`You should not change uri of the component (${componentPath})`);
|
|
121
187
|
/** Validate sub-components */
|
|
122
188
|
if (newChildMetadata.components && componentInstance) {
|
|
123
189
|
_validateComponents({
|
|
@@ -137,10 +203,10 @@ export var ProcessorFactory;
|
|
|
137
203
|
async function _configureComponents(ctx) {
|
|
138
204
|
const { newMetadataComponents, newProfileComponents, oldMetadataComponents, oldProfileComponents, curPath, owner, stackExecutor, processor, } = ctx;
|
|
139
205
|
if (!newMetadataComponents)
|
|
140
|
-
return;
|
|
206
|
+
return true;
|
|
141
207
|
owner.components = owner.components || {};
|
|
142
208
|
// Stack: components
|
|
143
|
-
await stackExecutor.executeAsync('components', async () => {
|
|
209
|
+
return await stackExecutor.executeAsync('components', async () => {
|
|
144
210
|
for (const [key, newChildMetadata] of Object.entries(newMetadataComponents)) {
|
|
145
211
|
// Stack: components/componentName
|
|
146
212
|
await stackExecutor.executeAsync(key, async () => {
|
|
@@ -153,17 +219,18 @@ export var ProcessorFactory;
|
|
|
153
219
|
const newChildProfile = newProfileComponents[key];
|
|
154
220
|
const componentPath = curPath ? curPath + '/' + key : key;
|
|
155
221
|
let componentInstance = owner.components[key];
|
|
156
|
-
/** Create the component
|
|
157
|
-
if (
|
|
222
|
+
/** Create the component */
|
|
223
|
+
if (!componentInstance) {
|
|
158
224
|
const compReg = ExtensionRegistry.getComponent(newChildMetadata.classUri);
|
|
159
225
|
/** Create the component instance */
|
|
160
226
|
const compClass = await compReg.getClass();
|
|
227
|
+
const values = { ...newChildProfile.values };
|
|
161
228
|
componentInstance = new compClass({
|
|
162
229
|
processor: processor,
|
|
163
230
|
parent: owner,
|
|
164
231
|
name: key,
|
|
165
232
|
path: componentPath,
|
|
166
|
-
values
|
|
233
|
+
values,
|
|
167
234
|
});
|
|
168
235
|
owner.components[key] = componentInstance;
|
|
169
236
|
if (newChildMetadata.propertyKey)
|
|
@@ -171,30 +238,7 @@ export var ProcessorFactory;
|
|
|
171
238
|
}
|
|
172
239
|
else {
|
|
173
240
|
componentInstance.values = {};
|
|
174
|
-
|
|
175
|
-
if (oldValues)
|
|
176
|
-
Object.assign(target, oldValues);
|
|
177
|
-
const updatedValues = ctx.valueUpdates.get(componentInstance) || [];
|
|
178
|
-
ctx.valueUpdates.set(componentInstance, updatedValues);
|
|
179
|
-
if (newVariables) {
|
|
180
|
-
for (const [varKey, varMeta] of Object.entries(newVariables)) {
|
|
181
|
-
const keyPath = valPath ? valPath + '.' + varKey : varKey;
|
|
182
|
-
/** Update only hotplug variables */
|
|
183
|
-
if (varMeta?.hotPlug !== true)
|
|
184
|
-
continue;
|
|
185
|
-
if (varMeta.type === 'nested') {
|
|
186
|
-
target[varKey] = {};
|
|
187
|
-
patchValues(target[varKey], keyPath, newValues[varKey], newVariables[varKey]?.variables || {}, oldValues?.[varKey], oldVariables?.[varKey]?.variables);
|
|
188
|
-
continue;
|
|
189
|
-
}
|
|
190
|
-
if (!equal(target[varKey], newValues[varKey])) {
|
|
191
|
-
updatedValues.push(keyPath);
|
|
192
|
-
target[varKey] = newValues[varKey];
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
};
|
|
197
|
-
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);
|
|
198
242
|
}
|
|
199
243
|
/** Create the child logger */
|
|
200
244
|
componentInstance.logger = owner.logger?.child({
|
|
@@ -204,7 +248,7 @@ export var ProcessorFactory;
|
|
|
204
248
|
componentInstance.logger.level =
|
|
205
249
|
newChildProfile.settings?.logs?.level;
|
|
206
250
|
}
|
|
207
|
-
/** Initialize sub
|
|
251
|
+
/** Initialize sub-components */
|
|
208
252
|
if (newChildMetadata.components) {
|
|
209
253
|
await _configureComponents({
|
|
210
254
|
...ctx,
|
|
@@ -221,4 +265,27 @@ export var ProcessorFactory;
|
|
|
221
265
|
}
|
|
222
266
|
});
|
|
223
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
|
+
}
|
|
224
291
|
})(ProcessorFactory || (ProcessorFactory = {}));
|
|
@@ -4,7 +4,7 @@ import { ComponentBase } from '../classes/component-base.js';
|
|
|
4
4
|
import { ProcessorBase } from '../classes/processor-base.js';
|
|
5
5
|
import { SbError } from '../classes/sb-error.js';
|
|
6
6
|
import { ComponentMetadata, ElementMetadata, ProcessorMetadata, } from '../models/index.js';
|
|
7
|
-
import { isComponentBase, isProcessorBase } from '../utils/type-
|
|
7
|
+
import { isComponentBase, isProcessorBase } from '../utils/type-guards.js';
|
|
8
8
|
/**
|
|
9
9
|
*
|
|
10
10
|
*/
|
|
@@ -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
|
|
13
|
+
issues: StackExecutor.Issue[];
|
|
14
|
+
} | {
|
|
15
|
+
result: false;
|
|
16
|
+
issues: StackExecutor.Issue[];
|
|
13
17
|
};
|
|
@@ -7,22 +7,22 @@ import { ExtensionRegistry } from '../registry/extension-registry.js';
|
|
|
7
7
|
* Materializes metadata from profile.
|
|
8
8
|
*/
|
|
9
9
|
export function materializeMetadata(profile, returnUndefinedComponentsAsAbstract) {
|
|
10
|
-
const
|
|
11
|
-
if (
|
|
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 {
|
|
52
|
-
return { metadata };
|
|
51
|
+
return { result: false, issues: stackExecutor.issues };
|
|
52
|
+
return { result: true, metadata, issues: stackExecutor.issues };
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
55
|
*
|
|
@@ -39,7 +39,8 @@ export async function normalizeProcessorMetadataSilent(metadata) {
|
|
|
39
39
|
cloned.variables = normalizeVariables(cloned.variables);
|
|
40
40
|
cloned.components = normalizeComponents(cloned.components);
|
|
41
41
|
const { value, errors } = decoder.silent(cloned);
|
|
42
|
-
|
|
42
|
+
if (value)
|
|
43
|
+
merge(value, metadata, { keepExisting: true, deep: 'full' });
|
|
43
44
|
return {
|
|
44
45
|
metadata: value || cloned,
|
|
45
46
|
issues: errors?.map(x => ({
|
|
@@ -84,7 +85,8 @@ export async function normalizeComponentMetadataSilent(metadata) {
|
|
|
84
85
|
cloned.variables = normalizeVariables(cloned.variables);
|
|
85
86
|
cloned.components = normalizeComponents(cloned.components);
|
|
86
87
|
const { value, errors } = decoder.silent(cloned);
|
|
87
|
-
|
|
88
|
+
if (value)
|
|
89
|
+
merge(value, metadata, { keepExisting: true, deep: 'full' });
|
|
88
90
|
return {
|
|
89
91
|
metadata: value || cloned,
|
|
90
92
|
issues: errors?.map(x => ({
|
|
File without changes
|
|
File without changes
|