@syncbridge/common 0.6.14 → 0.7.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 (38) hide show
  1. package/classes/base-element.d.ts +3 -0
  2. package/classes/base-element.js +3 -0
  3. package/constants.d.ts +2 -3
  4. package/constants.js +3 -11
  5. package/decorators/component.decorator.d.ts +5 -7
  6. package/decorators/component.decorator.js +57 -10
  7. package/decorators/decorator-helpers.d.ts +6 -1
  8. package/decorators/decorator-helpers.js +45 -10
  9. package/decorators/processor-events.decorator.js +14 -8
  10. package/decorators/processor.decorator.d.ts +6 -8
  11. package/decorators/processor.decorator.js +48 -3
  12. package/decorators/use-component.decorator.d.ts +1 -1
  13. package/decorators/use-component.decorator.js +12 -14
  14. package/decorators/use-variables.decorator.js +5 -6
  15. package/models/metadata/component-metadata.js +1 -1
  16. package/models/metadata/element-component-metadata.d.ts +1 -2
  17. package/models/metadata/element-component-metadata.js +4 -13
  18. package/models/metadata/element-metadata.d.ts +2 -1
  19. package/models/metadata/element-metadata.js +12 -4
  20. package/models/profile/profile-component.d.ts +1 -1
  21. package/models/profile/profile-component.js +3 -3
  22. package/models/profile/profile.d.ts +1 -1
  23. package/models/profile/profile.js +3 -3
  24. package/package.json +2 -1
  25. package/processor-factory.d.ts +2 -1
  26. package/processor-factory.js +26 -8
  27. package/registry/extension-package.d.ts +23 -13
  28. package/registry/extension-package.js +28 -22
  29. package/registry/extension-registry.d.ts +22 -15
  30. package/registry/extension-registry.js +122 -88
  31. package/utils/decode-profile.js +1 -1
  32. package/utils/locate-package-json.d.ts +5 -0
  33. package/{registry → utils}/locate-package-json.js +9 -2
  34. package/utils/materialize-metadata.js +24 -41
  35. package/utils/normalize-metadata.js +4 -2
  36. package/decorators/finalize-element-metadata.d.ts +0 -4
  37. package/decorators/finalize-element-metadata.js +0 -30
  38. package/registry/locate-package-json.d.ts +0 -4
@@ -1,5 +1,5 @@
1
1
  import equal from 'fast-deep-equal';
2
- import { SbError } from './classes/sb-error.js';
2
+ import { SbError, SbValidationError } from './classes/sb-error.js';
3
3
  import { StackExecutor } from './classes/stack-executor.js';
4
4
  import { initializeModelsDocument } from './models-document.js';
5
5
  import { ExtensionRegistry } from './registry/extension-registry.js';
@@ -9,8 +9,26 @@ export var ProcessorFactory;
9
9
  ProcessorFactory.METADATA_KEY = Symbol('METADATA');
10
10
  ProcessorFactory.PROFILE_KEY = Symbol('PROFILE');
11
11
  async function createProcessor(profile, options) {
12
+ const { processor: out, issues } = await createProcessorSilent(profile, options);
13
+ if (issues?.length) {
14
+ const msg = 'Error while creating processor.\n ' +
15
+ issues
16
+ .map(issue => `- ${issue.message}. Location: /${issue.location}`)
17
+ .join('\n ');
18
+ issues.forEach(issue => {
19
+ if (issue instanceof SbValidationError)
20
+ delete issue.stack;
21
+ });
22
+ throw new SbValidationError(msg, {
23
+ issues,
24
+ });
25
+ }
26
+ return out;
27
+ }
28
+ ProcessorFactory.createProcessor = createProcessor;
29
+ async function createProcessorSilent(profile, options) {
12
30
  await initializeModelsDocument();
13
- const reg = ExtensionRegistry.getProcessor(profile.processorClass, profile.processorVersion);
31
+ const reg = ExtensionRegistry.getProcessor(profile.processorUri, profile.processorVersion);
14
32
  const processorClass = await reg.getClass();
15
33
  const processor = new processorClass({
16
34
  name: profile.displayName,
@@ -31,7 +49,7 @@ export var ProcessorFactory;
31
49
  issues: ctx.stackExecutor.issues,
32
50
  };
33
51
  }
34
- ProcessorFactory.createProcessor = createProcessor;
52
+ ProcessorFactory.createProcessorSilent = createProcessorSilent;
35
53
  async function updateProcessor(processor, profile, options) {
36
54
  if (options?.logger)
37
55
  processor.logger = options.logger;
@@ -93,10 +111,10 @@ export var ProcessorFactory;
93
111
  const componentPath = curPath ? curPath + '/' + key : key;
94
112
  const componentInstance = owner.components?.[key];
95
113
  if (processor.stopped &&
96
- oldMetadata?.className &&
97
- oldMetadata?.className !== newMetadata.className)
114
+ oldMetadata?.uri &&
115
+ oldMetadata?.uri !== newMetadata.uri)
98
116
  throw new SbError('Cannot change component class while processor running. You should stop it first.');
99
- /** Validate sub components */
117
+ /** Validate sub-components */
100
118
  if (childMetadata.components && componentInstance) {
101
119
  _validateComponents({
102
120
  ...ctx,
@@ -130,7 +148,7 @@ export var ProcessorFactory;
130
148
  async function _configureComponent(ctx, key, childMetadata) {
131
149
  const { newProfile, oldMetadata, oldProfile, curPath, owner, processor } = ctx;
132
150
  const childProfile = newProfile.components[key];
133
- if (!childProfile?.className)
151
+ if (!childProfile?.uri)
134
152
  return;
135
153
  const oldChildMetadata = oldMetadata?.components?.[key];
136
154
  const oldChildProfile = oldProfile?.components?.[key];
@@ -138,7 +156,7 @@ export var ProcessorFactory;
138
156
  let componentInstance = owner.components?.[key];
139
157
  /** Create the component only if the owner stopped */ // todo implement hotplug components
140
158
  if (owner.stopped) {
141
- const compReg = ExtensionRegistry.getComponent(childMetadata.className);
159
+ const compReg = ExtensionRegistry.getComponent(childMetadata.uri);
142
160
  /** Create the component instance */
143
161
  const compClass = await compReg.getClass();
144
162
  componentInstance = new compClass({
@@ -1,8 +1,9 @@
1
1
  import 'reflect-metadata';
2
2
  import { Type } from 'ts-gems';
3
+ import { BaseElement } from '../classes/base-element.js';
3
4
  import { ComponentBase } from '../classes/component-base.js';
4
5
  import { ProcessorBase } from '../classes/processor-base.js';
5
- import { ComponentMetadata, ProcessorMetadata } from '../models/index.js';
6
+ import { ComponentMetadata, ElementMetadata, ProcessorMetadata } from '../models/index.js';
6
7
  /**
7
8
  *
8
9
  */
@@ -19,28 +20,37 @@ export declare class ExtensionPackage {
19
20
  /**
20
21
  *
21
22
  */
22
- export declare class ComponentExtension {
23
+ export declare abstract class ExtensionBase {
24
+ abstract readonly kind: 'component' | 'processor';
25
+ protected _ctor?: Type;
23
26
  readonly pkg: ExtensionPackage;
24
27
  readonly exportName: string;
25
- readonly metadata: ComponentMetadata;
26
- protected _ctor?: Type<ComponentBase>;
27
- constructor(pkg: ExtensionPackage, exportName: string, metadata: ComponentMetadata, ctor?: Type<ComponentBase>);
28
- get className(): string;
28
+ readonly metadata: ElementMetadata;
29
+ readonly name: string;
30
+ readonly packageName: string;
31
+ protected constructor(pkg: ExtensionPackage, exportName: string, metadata: ElementMetadata, ctor?: Type<BaseElement>);
32
+ get id(): string;
33
+ get uri(): string;
29
34
  get displayName(): string;
30
35
  get version(): string;
36
+ }
37
+ /**
38
+ *
39
+ */
40
+ export declare class ComponentExtension extends ExtensionBase {
41
+ readonly kind = "component";
42
+ protected _ctor?: Type<ComponentBase>;
43
+ readonly metadata: ComponentMetadata;
44
+ constructor(pkg: ExtensionPackage, exportName: string, metadata: ComponentMetadata, ctor?: Type<ComponentBase>);
31
45
  getClass(): Promise<Type<ComponentBase>>;
32
46
  }
33
47
  /**
34
48
  *
35
49
  */
36
- export declare class ProcessorExtension {
37
- readonly pkg: ExtensionPackage;
38
- readonly exportName: string;
39
- readonly metadata: ProcessorMetadata;
50
+ export declare class ProcessorExtension extends ExtensionBase {
51
+ readonly kind = "processor";
40
52
  protected _ctor?: Type<ProcessorBase>;
53
+ readonly metadata: ProcessorMetadata;
41
54
  constructor(pkg: ExtensionPackage, exportName: string, metadata: ProcessorMetadata, ctor?: Type<ProcessorBase>);
42
- get className(): string;
43
- get displayName(): string;
44
- get version(): string;
45
55
  getClass(): Promise<Type<ProcessorBase>>;
46
56
  }
@@ -12,19 +12,27 @@ export class ExtensionPackage {
12
12
  /**
13
13
  *
14
14
  */
15
- export class ComponentExtension {
15
+ export class ExtensionBase {
16
+ _ctor;
16
17
  pkg;
17
18
  exportName;
18
19
  metadata;
19
- _ctor;
20
+ name;
21
+ packageName;
20
22
  constructor(pkg, exportName, metadata, ctor) {
21
23
  this.pkg = pkg;
22
24
  this.exportName = exportName;
23
25
  this.metadata = metadata;
24
26
  this._ctor = ctor;
27
+ const [packageName, name] = metadata.uri.split(':');
28
+ this.name = name;
29
+ this.packageName = packageName;
30
+ }
31
+ get id() {
32
+ return this.metadata.id;
25
33
  }
26
- get className() {
27
- return this.metadata.className;
34
+ get uri() {
35
+ return this.metadata.uri;
28
36
  }
29
37
  get displayName() {
30
38
  return this.metadata.displayName;
@@ -32,6 +40,17 @@ export class ComponentExtension {
32
40
  get version() {
33
41
  return this.pkg.version;
34
42
  }
43
+ }
44
+ /**
45
+ *
46
+ */
47
+ export class ComponentExtension extends ExtensionBase {
48
+ kind = 'component';
49
+ constructor(pkg, exportName, metadata, ctor) {
50
+ super(pkg, exportName, metadata, ctor);
51
+ if (ctor && !isComponentBase(ctor.prototype))
52
+ throw new SbError(`${ctor.name} does not extends ComponentBase`);
53
+ }
35
54
  async getClass() {
36
55
  if (this._ctor)
37
56
  return this._ctor;
@@ -50,25 +69,12 @@ export class ComponentExtension {
50
69
  /**
51
70
  *
52
71
  */
53
- export class ProcessorExtension {
54
- pkg;
55
- exportName;
56
- metadata;
57
- _ctor;
72
+ export class ProcessorExtension extends ExtensionBase {
73
+ kind = 'processor';
58
74
  constructor(pkg, exportName, metadata, ctor) {
59
- this.pkg = pkg;
60
- this.exportName = exportName;
61
- this.metadata = metadata;
62
- this._ctor = ctor;
63
- }
64
- get className() {
65
- return this.metadata.className;
66
- }
67
- get displayName() {
68
- return this.metadata.displayName;
69
- }
70
- get version() {
71
- return this.pkg.version;
75
+ super(pkg, exportName, metadata, ctor);
76
+ if (ctor && !isProcessorBase(ctor.prototype))
77
+ throw new SbError(`${ctor.name} does not extends ProcessorBase`);
72
78
  }
73
79
  async getClass() {
74
80
  if (this._ctor)
@@ -1,5 +1,7 @@
1
1
  import { ResponsiveMap } from '@opra/common';
2
2
  import { Type } from 'ts-gems';
3
+ import { ComponentBase } from '../classes/component-base.js';
4
+ import { ProcessorBase } from '../classes/processor-base.js';
3
5
  import { ComponentExtension, ExtensionPackage, ProcessorExtension } from './extension-package.js';
4
6
  declare const instanceSymbol: unique symbol;
5
7
  /**
@@ -14,20 +16,28 @@ export declare class ExtensionRegistry {
14
16
  protected static [instanceSymbol]: ExtensionRegistry;
15
17
  static get packages(): ResponsiveMap<ExtensionPackage[]>;
16
18
  static get components(): ResponsiveMap<ComponentExtension[]>;
19
+ static get componentsById(): ResponsiveMap<ComponentExtension[]>;
20
+ static get componentsByClassName(): ResponsiveMap<ComponentExtension[]>;
17
21
  static get processors(): ResponsiveMap<ProcessorExtension[]>;
22
+ static get processorsById(): ResponsiveMap<ProcessorExtension[]>;
23
+ static get processorsByClassName(): ResponsiveMap<ProcessorExtension[]>;
18
24
  static setResolver(fn: ExtensionRegistry.PackageResolver | undefined): void;
19
- static findComponent(className: string, version?: string): ComponentExtension | undefined;
20
- static getComponent(className: string, version?: string): ComponentExtension;
21
- static findProcessor(className: string, version?: string): ProcessorExtension | undefined;
22
- static getProcessor(className: string, version?: string): ProcessorExtension;
25
+ static findComponent(uri: string, version?: string): ComponentExtension | undefined;
26
+ static getComponent(uri: string, version?: string): ComponentExtension;
27
+ static findProcessor(uri: string, version?: string): ProcessorExtension | undefined;
28
+ static getProcessor(uri: string, version?: string): ProcessorExtension;
23
29
  static registerPackage(specifier: string): Promise<ExtensionPackage>;
24
- static registerComponent(ctor: Type): Promise<ComponentExtension | undefined>;
25
- static registerProcessor(ctor: Type): Promise<ProcessorExtension | undefined>;
30
+ static registerClass<T extends ComponentBase>(ctor: Type<T>): Promise<ComponentExtension>;
31
+ static registerClass<T extends ProcessorBase>(ctor: Type<T>): Promise<ProcessorExtension>;
26
32
  static storePackage(pkg: ExtensionPackage): void;
27
33
  protected _resolver: ExtensionRegistry.PackageResolver;
28
34
  readonly packages: ResponsiveMap<ExtensionPackage[]>;
29
35
  readonly components: ResponsiveMap<ComponentExtension[]>;
36
+ readonly componentsById: ResponsiveMap<ComponentExtension[]>;
37
+ readonly componentsByClassName: ResponsiveMap<ComponentExtension[]>;
30
38
  readonly processors: ResponsiveMap<ProcessorExtension[]>;
39
+ readonly processorsById: ResponsiveMap<ProcessorExtension[]>;
40
+ readonly processorsByClassName: ResponsiveMap<ProcessorExtension[]>;
31
41
  /**
32
42
  *
33
43
  */
@@ -35,28 +45,25 @@ export declare class ExtensionRegistry {
35
45
  /**
36
46
  *
37
47
  */
38
- findComponent(className: string, version?: string): ComponentExtension | undefined;
48
+ findComponent(uri: string, version?: string): ComponentExtension | undefined;
39
49
  /**
40
50
  *
41
51
  */
42
- getComponent(className: string, version?: string): ComponentExtension;
52
+ getComponent(uri: string, version?: string): ComponentExtension;
43
53
  /**
44
54
  *
45
55
  */
46
- findProcessor(className: string, version?: string): ProcessorExtension | undefined;
56
+ findProcessor(uri: string, version?: string): ProcessorExtension | undefined;
47
57
  /**
48
58
  *
49
59
  */
50
- getProcessor(className: string, version?: string): ProcessorExtension;
60
+ getProcessor(uri: string, version?: string): ProcessorExtension;
51
61
  /**
52
62
  *
53
63
  */
54
64
  registerPackage(specifier: string): Promise<ExtensionPackage>;
55
- registerComponent(ctor: Type): Promise<ComponentExtension | undefined>;
56
- /**
57
- *
58
- */
59
- registerProcessor(ctor: Type): Promise<ProcessorExtension | undefined>;
65
+ registerClass<T extends ComponentBase>(ctor: Type<T>): Promise<ComponentExtension>;
66
+ registerClass<T extends ProcessorBase>(ctor: Type<T>): Promise<ProcessorExtension>;
60
67
  /**
61
68
  *
62
69
  */
@@ -5,10 +5,10 @@ import { updateErrorMessage } from '@jsopen/objects';
5
5
  import { ResponsiveMap } from '@opra/common';
6
6
  import semver from 'semver';
7
7
  import { SbError } from '../classes/sb-error.js';
8
- import { COMPONENT_OPTIONS, PROCESSOR_OPTIONS } from '../constants.js';
8
+ import { CLASS_METADATA, CLASS_TYPE } from '../constants.js';
9
+ import { locatePackageJson } from '../utils/locate-package-json.js';
9
10
  import { normalizeComponentMetadata, normalizeProcessorMetadata, } from '../utils/normalize-metadata.js';
10
11
  import { ComponentExtension, ExtensionPackage, ProcessorExtension, } from './extension-package.js';
11
- import { locatePackageJson } from './locate-package-json.js';
12
12
  const instanceSymbol = Symbol.for('instance');
13
13
  /**
14
14
  * The `ExtensionRegistry` class is responsible for managing component and processor extensions,
@@ -26,32 +26,41 @@ export class ExtensionRegistry {
26
26
  static get components() {
27
27
  return this[instanceSymbol].components;
28
28
  }
29
+ static get componentsById() {
30
+ return this[instanceSymbol].componentsById;
31
+ }
32
+ static get componentsByClassName() {
33
+ return this[instanceSymbol].componentsByClassName;
34
+ }
29
35
  static get processors() {
30
36
  return this[instanceSymbol].processors;
31
37
  }
38
+ static get processorsById() {
39
+ return this[instanceSymbol].processorsById;
40
+ }
41
+ static get processorsByClassName() {
42
+ return this[instanceSymbol].processorsByClassName;
43
+ }
32
44
  static setResolver(fn) {
33
45
  this[instanceSymbol].setResolver(fn);
34
46
  }
35
- static findComponent(className, version = '*') {
36
- return this[instanceSymbol].findComponent(className, version);
47
+ static findComponent(uri, version = '*') {
48
+ return this[instanceSymbol].findComponent(uri, version);
37
49
  }
38
- static getComponent(className, version = '*') {
39
- return this[instanceSymbol].getComponent(className, version);
50
+ static getComponent(uri, version = '*') {
51
+ return this[instanceSymbol].getComponent(uri, version);
40
52
  }
41
- static findProcessor(className, version = '*') {
42
- return this[instanceSymbol].findProcessor(className, version);
53
+ static findProcessor(uri, version = '*') {
54
+ return this[instanceSymbol].findProcessor(uri, version);
43
55
  }
44
- static getProcessor(className, version = '*') {
45
- return this[instanceSymbol].getProcessor(className, version);
56
+ static getProcessor(uri, version = '*') {
57
+ return this[instanceSymbol].getProcessor(uri, version);
46
58
  }
47
59
  static async registerPackage(specifier) {
48
60
  return this[instanceSymbol].registerPackage(specifier);
49
61
  }
50
- static async registerComponent(ctor) {
51
- return this[instanceSymbol].registerComponent(ctor);
52
- }
53
- static async registerProcessor(ctor) {
54
- return this[instanceSymbol].registerProcessor(ctor);
62
+ static async registerClass(ctor) {
63
+ return this[instanceSymbol].registerClass(ctor);
55
64
  }
56
65
  static storePackage(pkg) {
57
66
  return this[instanceSymbol].storePackage(pkg);
@@ -59,7 +68,11 @@ export class ExtensionRegistry {
59
68
  _resolver = import.meta.resolve;
60
69
  packages = new ResponsiveMap();
61
70
  components = new ResponsiveMap();
71
+ componentsById = new ResponsiveMap();
72
+ componentsByClassName = new ResponsiveMap();
62
73
  processors = new ResponsiveMap();
74
+ processorsById = new ResponsiveMap();
75
+ processorsByClassName = new ResponsiveMap();
63
76
  /**
64
77
  *
65
78
  */
@@ -69,36 +82,32 @@ export class ExtensionRegistry {
69
82
  /**
70
83
  *
71
84
  */
72
- findComponent(className, version = '*') {
73
- return this.components
74
- .get(className)
75
- ?.find(v => semver.satisfies(v.version, version || '*'));
85
+ findComponent(uri, version = '*') {
86
+ return (this.components.get(uri) || this.componentsById.get(uri))?.find(v => semver.satisfies(v.version, version || '*'));
76
87
  }
77
88
  /**
78
89
  *
79
90
  */
80
- getComponent(className, version = '*') {
81
- const cmp = this.findComponent(className, version);
91
+ getComponent(uri, version = '*') {
92
+ const cmp = this.findComponent(uri, version);
82
93
  if (!cmp) {
83
- throw new SbError(`Component "${className}@${version}" not found in registry`);
94
+ throw new SbError(`Component "${uri}@${version}" not found in registry`);
84
95
  }
85
96
  return cmp;
86
97
  }
87
98
  /**
88
99
  *
89
100
  */
90
- findProcessor(className, version = '*') {
91
- return this.processors
92
- .get(className)
93
- ?.find(v => semver.satisfies(v.version, version || '*'));
101
+ findProcessor(uri, version = '*') {
102
+ return (this.processors.get(uri) || this.processorsById.get(uri))?.find(v => semver.satisfies(v.version, version || '*'));
94
103
  }
95
104
  /**
96
105
  *
97
106
  */
98
- getProcessor(className, version = '*') {
99
- const cmp = this.findProcessor(className, version);
107
+ getProcessor(uri, version = '*') {
108
+ const cmp = this.findProcessor(uri, version);
100
109
  if (!cmp) {
101
- throw new SbError(`Processor "${className}@${version}" not found in registry`);
110
+ throw new SbError(`Processor "${uri}@${version}" not found in registry`);
102
111
  }
103
112
  return cmp;
104
113
  }
@@ -116,7 +125,7 @@ export class ExtensionRegistry {
116
125
  entryPoint = pathToFileURL(entryPoint).href;
117
126
  }
118
127
  const pkg = new ExtensionPackage();
119
- pkg.name = pkgJson.name;
128
+ pkg.name = pkgJson.syncbridge?.name || pkgJson.name;
120
129
  pkg.version = pkgJson.version;
121
130
  pkg.description = pkgJson.description;
122
131
  pkg.path = pkgDir;
@@ -125,8 +134,11 @@ export class ExtensionRegistry {
125
134
  for (const [ctorName, v] of Object.entries(module)) {
126
135
  if (typeof v !== 'function')
127
136
  continue;
128
- let metadata = Reflect.getMetadata(COMPONENT_OPTIONS, v);
129
- if (metadata) {
137
+ const classType = Reflect.getMetadata(CLASS_TYPE, v);
138
+ let metadata = Reflect.getMetadata(CLASS_METADATA, v);
139
+ if (!metadata)
140
+ continue;
141
+ if (classType === 'component') {
130
142
  try {
131
143
  metadata = await normalizeComponentMetadata(metadata);
132
144
  }
@@ -140,8 +152,7 @@ export class ExtensionRegistry {
140
152
  pkg.components = pkg.components || [];
141
153
  pkg.components.push(new ComponentExtension(pkg, ctorName, metadata));
142
154
  }
143
- metadata = Reflect.getMetadata(PROCESSOR_OPTIONS, v);
144
- if (metadata) {
155
+ else if (classType === 'processor') {
145
156
  try {
146
157
  metadata = await normalizeProcessorMetadata(metadata);
147
158
  }
@@ -159,56 +170,49 @@ export class ExtensionRegistry {
159
170
  this.storePackage(pkg);
160
171
  return pkg;
161
172
  }
162
- async registerComponent(ctor) {
163
- const _metadata = Reflect.getMetadata(COMPONENT_OPTIONS, ctor);
164
- if (!_metadata)
165
- throw new SbError(`Class "${ctor.name}" has no component metadata.`);
166
- if (_metadata.abstract)
167
- return;
168
- const metadata = await normalizeComponentMetadata(_metadata);
169
- let versions = this.packages.get('internal');
170
- if (!versions) {
171
- versions = [];
172
- this.packages.set('internal', versions);
173
+ async registerClass(ctor) {
174
+ let metadata = Reflect.getMetadata(CLASS_METADATA, ctor);
175
+ if (!metadata)
176
+ throw new TypeError(`Class "${ctor.name}" has no component metadata.`);
177
+ if (metadata.abstract)
178
+ throw new TypeError('Can not register an abstract class');
179
+ const classType = Reflect.getMetadata(CLASS_TYPE, ctor);
180
+ if (classType === 'component') {
181
+ metadata = await normalizeComponentMetadata(metadata);
173
182
  }
174
- let pkg = versions[0];
175
- if (!pkg) {
176
- pkg = new ExtensionPackage();
177
- pkg.name = 'internal';
178
- pkg.version = '0.0.0';
179
- pkg.description = 'Internal extensions';
183
+ else if (classType === 'processor') {
184
+ metadata = await normalizeProcessorMetadata(metadata);
180
185
  }
181
- const cmp = new ComponentExtension(pkg, ctor.name, metadata, ctor);
182
- pkg.components.push(cmp);
183
- this.storePackage(pkg);
184
- return cmp;
185
- }
186
- /**
187
- *
188
- */
189
- async registerProcessor(ctor) {
190
- const _metadata = Reflect.getMetadata(PROCESSOR_OPTIONS, ctor);
191
- if (!_metadata)
192
- throw new SbError(`Class "${ctor.name}" has no processor metadata.`);
193
- if (_metadata.abstract)
194
- return;
195
- const metadata = await normalizeProcessorMetadata(_metadata);
196
- let versions = this.packages.get('internal');
186
+ else
187
+ /* c8 ignore next */
188
+ throw new TypeError(`Invalid CLASS_TYPE metadata in "${ctor.name}".`);
189
+ const [packageName, className] = metadata.uri.split(':');
190
+ /* c8 ignore next */
191
+ if (!(packageName && className))
192
+ throw new TypeError(`Invalid metadata.uri value in ${ctor.name}"`);
193
+ const version = metadata.version || '0.0.0';
194
+ let versions = this.packages.get(packageName);
197
195
  if (!versions) {
198
196
  versions = [];
199
- this.packages.set('internal', versions);
197
+ this.packages.set(packageName, versions);
200
198
  }
201
199
  let pkg = versions[0];
202
200
  if (!pkg) {
203
201
  pkg = new ExtensionPackage();
204
- pkg.name = 'internal';
205
- pkg.version = '0.0.0';
206
- pkg.description = 'Internal extensions';
202
+ pkg.name = packageName;
203
+ pkg.version = version;
204
+ }
205
+ let out;
206
+ if (classType === 'component') {
207
+ out = new ComponentExtension(pkg, ctor.name, metadata, ctor);
208
+ pkg.components.push(out);
209
+ }
210
+ else {
211
+ out = new ProcessorExtension(pkg, ctor.name, metadata, ctor);
212
+ pkg.processors.push(out);
207
213
  }
208
- const prc = new ProcessorExtension(pkg, ctor.name, metadata, ctor);
209
- pkg.processors.push(prc);
210
214
  this.storePackage(pkg);
211
- return prc;
215
+ return out;
212
216
  }
213
217
  /**
214
218
  *
@@ -227,30 +231,60 @@ export class ExtensionRegistry {
227
231
  pkgVersions.sort((a, b) => a.version.localeCompare(b.version));
228
232
  if (pkg.components?.length) {
229
233
  for (const cmp of pkg.components) {
230
- let versions = this.components.get(cmp.className);
231
- if (!versions) {
232
- versions = [];
233
- this.components.set(cmp.className, versions);
234
+ if (this.processors.get(cmp.uri))
235
+ throw new SbError(`Component "${cmp.uri}" is already registered as a processor.`);
236
+ /** Store to components */
237
+ let items = this.components.get(cmp.uri);
238
+ if (!items) {
239
+ items = [];
240
+ this.components.set(cmp.uri, items);
241
+ this.componentsById.set(cmp.id, items);
234
242
  }
235
- i = versions.findIndex(v => v.version === cmp.version);
243
+ i = items.findIndex(v => v.version === cmp.version);
236
244
  if (i >= 0)
237
- versions[i] = cmp;
245
+ items[i] = cmp;
238
246
  else
239
- versions.push(cmp);
247
+ items.push(cmp);
248
+ /** Store to componentsByClassName */
249
+ items = this.componentsByClassName.get(cmp.name);
250
+ if (!items) {
251
+ items = [];
252
+ this.componentsByClassName.set(cmp.name, items);
253
+ }
254
+ i = items.findIndex(v => v.version === cmp.version);
255
+ if (i >= 0)
256
+ items[i] = cmp;
257
+ else
258
+ items.push(cmp);
240
259
  }
241
260
  }
242
261
  if (pkg.processors?.length) {
243
262
  for (const prc of pkg.processors) {
244
- let versions = this.processors.get(prc.className);
245
- if (!versions) {
246
- versions = [];
247
- this.processors.set(prc.className, versions);
263
+ if (this.components.get(prc.uri))
264
+ throw new SbError(`Processor "${prc.uri}" is already registered as a component.`);
265
+ /** Store to processors */
266
+ let items = this.processors.get(prc.uri);
267
+ if (!items) {
268
+ items = [];
269
+ this.processors.set(prc.uri, items);
270
+ this.processorsById.set(prc.id, items);
271
+ }
272
+ i = items.findIndex(v => v.version === prc.version);
273
+ if (i >= 0)
274
+ items[i] = prc;
275
+ else
276
+ items.push(prc);
277
+ /** Store to componentsByClassName */
278
+ items = this.processors.get(prc.name);
279
+ if (!items) {
280
+ items = [];
281
+ this.processorsByClassName.set(prc.name, items);
248
282
  }
249
- i = versions.findIndex(v => v.version === prc.version);
283
+ i = items.findIndex(v => v.version === prc.version);
250
284
  if (i >= 0)
251
- versions[i] = prc;
285
+ items[i] = prc;
252
286
  else
253
- versions.push(prc);
287
+ items.push(prc);
254
288
  }
255
289
  }
256
290
  }
@@ -64,7 +64,7 @@ export function encodeProfileSilent(metadata, rawProfile, options) {
64
64
  const fn = t.generateCodec('encode', { coerce: true });
65
65
  const out = fn({
66
66
  id: rawProfile.id,
67
- processorClass: rawProfile.processorClass,
67
+ processorUri: rawProfile.processorUri,
68
68
  displayName: rawProfile.displayName,
69
69
  group: rawProfile.group,
70
70
  description: rawProfile.description,
@@ -0,0 +1,5 @@
1
+ /**
2
+ *
3
+ */
4
+ export declare function locatePackageJson(directory: string, depth?: number): string | undefined;
5
+ export declare function resolvePackageJson(directory: string): any | undefined;
@@ -4,10 +4,10 @@ import { fileURLToPath } from 'node:url';
4
4
  /**
5
5
  *
6
6
  */
7
- export function locatePackageJson(directory) {
7
+ export function locatePackageJson(directory, depth = 10) {
8
8
  if (directory.startsWith('file:'))
9
9
  directory = fileURLToPath(directory);
10
- for (let i = 0; i < 3; i++) {
10
+ for (let i = 0; i < depth; i++) {
11
11
  const f = path.resolve(directory, 'package.json');
12
12
  if (fs.existsSync(f)) {
13
13
  return directory;
@@ -15,3 +15,10 @@ export function locatePackageJson(directory) {
15
15
  directory = path.dirname(directory);
16
16
  }
17
17
  }
18
+ export function resolvePackageJson(directory) {
19
+ const pkg = locatePackageJson(directory);
20
+ if (!pkg)
21
+ return;
22
+ const content = fs.readFileSync(path.resolve(pkg, 'package.json'), 'utf-8');
23
+ return JSON.parse(content);
24
+ }