@syncbridge/common 1.1.4 → 2.0.1
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/README.md +192 -1
- package/app-factory.d.ts +29 -0
- package/{processor-factory.js → app-factory.js} +63 -44
- package/classes/{processor-base.d.ts → app-base.d.ts} +3 -3
- package/classes/app-base.js +10 -0
- package/classes/base-element.d.ts +3 -0
- package/classes/base-element.js +2 -1
- package/classes/component-base.d.ts +6 -6
- package/classes/component-base.js +2 -3
- package/classes/console-logger.js +0 -1
- package/classes/frame-stream.js +0 -1
- package/classes/log-channel-writer.d.ts +32 -0
- package/classes/log-channel-writer.js +96 -0
- package/classes/runnable.d.ts +6 -0
- package/classes/runnable.js +22 -1
- package/classes/sb-error.js +0 -1
- package/classes/stack-executor.js +0 -1
- package/constants.d.ts +1 -1
- package/constants.js +1 -2
- package/decorators/app-events.decorator.d.ts +5 -0
- package/decorators/{processor-events.decorator.js → app-events.decorator.js} +0 -1
- package/decorators/app.decorator.d.ts +29 -0
- package/decorators/{processor.decorator.js → app.decorator.js} +24 -19
- package/decorators/component.decorator.js +13 -6
- package/decorators/decorator-helpers.js +0 -1
- package/decorators/define-variable.decorator.d.ts +6 -1
- package/decorators/define-variable.decorator.js +5 -2
- package/decorators/log-channel.decorator.d.ts +97 -0
- package/decorators/log-channel.decorator.js +33 -0
- package/decorators/use-component.decorator.d.ts +2 -2
- package/decorators/use-component.decorator.js +1 -2
- package/decorators/use-variables.decorator.d.ts +2 -2
- package/decorators/use-variables.decorator.js +0 -1
- package/host-link/host-identity.d.ts +53 -0
- package/host-link/host-identity.js +139 -0
- package/host-link/host-link.d.ts +43 -0
- package/host-link/host-link.js +53 -0
- package/host-link/host-packages.d.ts +25 -0
- package/host-link/host-packages.js +9 -0
- package/host-link/host-workers.d.ts +75 -0
- package/host-link/host-workers.js +28 -0
- package/host-link/multiplexer.d.ts +115 -0
- package/host-link/multiplexer.js +288 -0
- package/host-link/sealed-box.d.ts +21 -0
- package/host-link/sealed-box.js +103 -0
- package/index.d.ts +16 -3
- package/index.js +16 -4
- package/interfaces/index.js +0 -1
- package/interfaces/logger.interface.js +0 -1
- package/models/enums/enum-source.enum.d.ts +11 -0
- package/models/enums/enum-source.enum.js +21 -0
- package/models/enums/log-channel-kind.d.ts +7 -0
- package/models/enums/log-channel-kind.js +13 -0
- package/models/enums/log-level.js +0 -1
- package/models/enums/service-status.d.ts +5 -1
- package/models/enums/service-status.js +4 -1
- package/models/enums/variable-format.enum.js +0 -1
- package/models/enums/variable-type.enum.js +0 -1
- package/models/enums/worker-permission.enum.d.ts +16 -0
- package/models/enums/worker-permission.enum.js +27 -0
- package/models/index.d.ts +6 -1
- package/models/index.js +6 -2
- package/models/metadata/app-metadata.d.ts +6 -0
- package/models/metadata/{processor-metadata.js → app-metadata.js} +6 -7
- package/models/metadata/component-metadata.js +0 -1
- package/models/metadata/element-component-metadata.d.ts +2 -0
- package/models/metadata/element-component-metadata.js +10 -3
- package/models/metadata/element-metadata.d.ts +8 -0
- package/models/metadata/element-metadata.js +40 -1
- package/models/metadata/log-channel-metadata.d.ts +23 -0
- package/models/metadata/log-channel-metadata.js +72 -0
- package/models/metadata/package-metadata.js +0 -1
- package/models/metadata/plugin-metadata.d.ts +15 -0
- package/models/metadata/plugin-metadata.js +65 -0
- package/models/metadata/variable-metadata.d.ts +3 -0
- package/models/metadata/variable-metadata.js +15 -2
- package/models/profile/log-options.d.ts +17 -0
- package/models/profile/log-options.js +58 -2
- package/models/profile/profile-component.js +0 -1
- package/models/profile/profile.d.ts +2 -2
- package/models/profile/profile.js +9 -10
- package/models-document.js +0 -1
- package/package.json +6 -2
- package/registry/docs-sidebar.d.ts +59 -0
- package/registry/docs-sidebar.js +169 -0
- package/registry/extension-package.d.ts +40 -13
- package/registry/extension-package.js +59 -19
- package/registry/extension-registry.d.ts +16 -16
- package/registry/extension-registry.js +59 -45
- package/registry/module-catalog.d.ts +31 -0
- package/registry/module-catalog.js +88 -0
- package/registry/package-docs.d.ts +98 -0
- package/registry/package-docs.js +159 -0
- package/registry/package-manifest.d.ts +54 -3
- package/registry/package-manifest.js +59 -2
- package/utils/decode-profile.d.ts +18 -2
- package/utils/decode-profile.js +65 -10
- package/utils/encrypt-helpers.d.ts +7 -0
- package/utils/encrypt-helpers.js +12 -6
- package/utils/locate-package-json.js +0 -1
- package/utils/materialize-metadata.d.ts +3 -3
- package/utils/materialize-metadata.js +16 -13
- package/utils/normalize-metadata.d.ts +23 -4
- package/utils/normalize-metadata.js +52 -7
- package/utils/registry-names.js +0 -1
- package/utils/resolve-promises.js +0 -1
- package/utils/type-guards.d.ts +2 -2
- package/utils/type-guards.js +4 -5
- package/utils/uri-to-id.js +0 -1
- package/utils/worker-permissions.d.ts +25 -0
- package/utils/worker-permissions.js +59 -0
- package/classes/base-element.js.map +0 -1
- package/classes/component-base.js.map +0 -1
- package/classes/console-logger.js.map +0 -1
- package/classes/frame-stream.js.map +0 -1
- package/classes/processor-base.js +0 -11
- package/classes/processor-base.js.map +0 -1
- package/classes/runnable.js.map +0 -1
- package/classes/sb-error.js.map +0 -1
- package/classes/stack-executor.js.map +0 -1
- package/constants.js.map +0 -1
- package/decorators/component.decorator.js.map +0 -1
- package/decorators/decorator-helpers.js.map +0 -1
- package/decorators/define-variable.decorator.js.map +0 -1
- package/decorators/processor-events.decorator.d.ts +0 -5
- package/decorators/processor-events.decorator.js.map +0 -1
- package/decorators/processor.decorator.d.ts +0 -29
- package/decorators/processor.decorator.js.map +0 -1
- package/decorators/use-component.decorator.js.map +0 -1
- package/decorators/use-variables.decorator.js.map +0 -1
- package/index.js.map +0 -1
- package/interfaces/index.js.map +0 -1
- package/interfaces/logger.interface.js.map +0 -1
- package/models/enums/log-level.js.map +0 -1
- package/models/enums/service-status.js.map +0 -1
- package/models/enums/variable-format.enum.js.map +0 -1
- package/models/enums/variable-type.enum.js.map +0 -1
- package/models/index.js.map +0 -1
- package/models/metadata/component-metadata.js.map +0 -1
- package/models/metadata/element-component-metadata.js.map +0 -1
- package/models/metadata/element-metadata.js.map +0 -1
- package/models/metadata/package-metadata.js.map +0 -1
- package/models/metadata/processor-metadata.d.ts +0 -6
- package/models/metadata/processor-metadata.js.map +0 -1
- package/models/metadata/variable-metadata.js.map +0 -1
- package/models/profile/log-options.js.map +0 -1
- package/models/profile/profile-component.js.map +0 -1
- package/models/profile/profile.js.map +0 -1
- package/models-document.js.map +0 -1
- package/processor-factory.d.ts +0 -26
- package/processor-factory.js.map +0 -1
- package/registry/extension-package.js.map +0 -1
- package/registry/extension-registry.js.map +0 -1
- package/registry/package-manifest.js.map +0 -1
- package/utils/decode-profile.js.map +0 -1
- package/utils/encrypt-helpers.js.map +0 -1
- package/utils/locate-package-json.js.map +0 -1
- package/utils/materialize-metadata.js.map +0 -1
- package/utils/normalize-metadata.js.map +0 -1
- package/utils/registry-names.js.map +0 -1
- package/utils/resolve-promises.js.map +0 -1
- package/utils/type-guards.js.map +0 -1
- package/utils/uri-to-id.js.map +0 -1
package/models-document.js
CHANGED
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syncbridge/common",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "SyncBridge Common utilities",
|
|
5
5
|
"author": "Panates Inc",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/
|
|
9
|
+
"url": "git+https://github.com/syncbridge-io/node-sdk.git",
|
|
10
10
|
"directory": "packages/common"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
@@ -37,5 +37,9 @@
|
|
|
37
37
|
},
|
|
38
38
|
"publishConfig": {
|
|
39
39
|
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/syncbridge-io/node-sdk/tree/main/packages/common#readme",
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/syncbridge-io/node-sdk/issues"
|
|
40
44
|
}
|
|
41
45
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a package's documents are listed, where its author tells it: a
|
|
3
|
+
* sidebar.json in docs/ (the package's own) or in docs/<ClassName>/ (an
|
|
4
|
+
* app's, component's or plugin's). Without one they are listed by their
|
|
5
|
+
* front matter's order and titles.
|
|
6
|
+
*
|
|
7
|
+
* {
|
|
8
|
+
* "items": [
|
|
9
|
+
* "README.md",
|
|
10
|
+
* { "doc": "user-guide.pdf",
|
|
11
|
+
* "title": { "tr": "Kullanım kılavuzu", "en": "User guide" } },
|
|
12
|
+
* { "label": { "tr": "Ağ", "en": "Network" },
|
|
13
|
+
* "items": ["network.md", "firewall.md"] }
|
|
14
|
+
* ]
|
|
15
|
+
* }
|
|
16
|
+
*
|
|
17
|
+
* A document is named as it is in the package's own language, from where
|
|
18
|
+
* the sidebar is - its languages are found by its name (network.md for
|
|
19
|
+
* network.tr.md). A title is text, or text by language. A document not
|
|
20
|
+
* listed is read by a link to it alone.
|
|
21
|
+
*/
|
|
22
|
+
export declare const SIDEBAR_FILE = "sidebar.json";
|
|
23
|
+
/** Text, or text by language: { "tr": "Ağ", "en": "Network" } */
|
|
24
|
+
export type SidebarText = string | Record<string, string>;
|
|
25
|
+
/** An item of a sidebar, as its author writes it */
|
|
26
|
+
export type SidebarItemSource = string | {
|
|
27
|
+
doc: string;
|
|
28
|
+
title?: SidebarText;
|
|
29
|
+
} | {
|
|
30
|
+
label: SidebarText;
|
|
31
|
+
items: SidebarItemSource[];
|
|
32
|
+
};
|
|
33
|
+
/** An item of a sidebar as kept: each document by its path in the package */
|
|
34
|
+
export type SidebarItem = {
|
|
35
|
+
doc: string;
|
|
36
|
+
title?: SidebarText;
|
|
37
|
+
} | {
|
|
38
|
+
label: SidebarText;
|
|
39
|
+
items: SidebarItem[];
|
|
40
|
+
};
|
|
41
|
+
/** A sidebar as kept: its items, each document by its path in the package */
|
|
42
|
+
export interface DocsSidebar {
|
|
43
|
+
items: SidebarItem[];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Whose a sidebar is, by its path in the package: '' for docs/sidebar.json
|
|
47
|
+
* (the package's own), the class for docs/<ClassName>/sidebar.json; none
|
|
48
|
+
* if it is not where a sidebar may be
|
|
49
|
+
*/
|
|
50
|
+
export declare function sidebarOwner(file: string): string | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* Reads a sidebar: what its author wrote, each document found among `docs`
|
|
53
|
+
* - the paths, in the package's own language, the package's documents are
|
|
54
|
+
* read by (docs/Gw/network.md, for network.md and network.tr.md alike).
|
|
55
|
+
* Throws, telling every problem, when it is not one.
|
|
56
|
+
*/
|
|
57
|
+
export declare function parseSidebar(file: string, source: unknown, docs: ReadonlySet<string>): DocsSidebar;
|
|
58
|
+
/** The documents a sidebar lists, by their paths */
|
|
59
|
+
export declare function sidebarDocs(sidebar: DocsSidebar): string[];
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { SbError } from '../classes/sb-error.js';
|
|
2
|
+
import { CLASS_DIR_PATTERN, DOCS_DIR, isDocsLanguage } from './package-docs.js';
|
|
3
|
+
/**
|
|
4
|
+
* How a package's documents are listed, where its author tells it: a
|
|
5
|
+
* sidebar.json in docs/ (the package's own) or in docs/<ClassName>/ (an
|
|
6
|
+
* app's, component's or plugin's). Without one they are listed by their
|
|
7
|
+
* front matter's order and titles.
|
|
8
|
+
*
|
|
9
|
+
* {
|
|
10
|
+
* "items": [
|
|
11
|
+
* "README.md",
|
|
12
|
+
* { "doc": "user-guide.pdf",
|
|
13
|
+
* "title": { "tr": "Kullanım kılavuzu", "en": "User guide" } },
|
|
14
|
+
* { "label": { "tr": "Ağ", "en": "Network" },
|
|
15
|
+
* "items": ["network.md", "firewall.md"] }
|
|
16
|
+
* ]
|
|
17
|
+
* }
|
|
18
|
+
*
|
|
19
|
+
* A document is named as it is in the package's own language, from where
|
|
20
|
+
* the sidebar is - its languages are found by its name (network.md for
|
|
21
|
+
* network.tr.md). A title is text, or text by language. A document not
|
|
22
|
+
* listed is read by a link to it alone.
|
|
23
|
+
*/
|
|
24
|
+
export const SIDEBAR_FILE = 'sidebar.json';
|
|
25
|
+
/** Categories within categories, at most */
|
|
26
|
+
const MAX_DEPTH = 3;
|
|
27
|
+
/**
|
|
28
|
+
* Whose a sidebar is, by its path in the package: '' for docs/sidebar.json
|
|
29
|
+
* (the package's own), the class for docs/<ClassName>/sidebar.json; none
|
|
30
|
+
* if it is not where a sidebar may be
|
|
31
|
+
*/
|
|
32
|
+
export function sidebarOwner(file) {
|
|
33
|
+
const parts = file.split('/');
|
|
34
|
+
if (parts[0] !== DOCS_DIR || parts[parts.length - 1] !== SIDEBAR_FILE)
|
|
35
|
+
return;
|
|
36
|
+
if (parts.length === 2)
|
|
37
|
+
return '';
|
|
38
|
+
if (parts.length === 3 && CLASS_DIR_PATTERN.test(parts[1]))
|
|
39
|
+
return parts[1];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Reads a sidebar: what its author wrote, each document found among `docs`
|
|
43
|
+
* - the paths, in the package's own language, the package's documents are
|
|
44
|
+
* read by (docs/Gw/network.md, for network.md and network.tr.md alike).
|
|
45
|
+
* Throws, telling every problem, when it is not one.
|
|
46
|
+
*/
|
|
47
|
+
export function parseSidebar(file, source, docs) {
|
|
48
|
+
const owner = sidebarOwner(file);
|
|
49
|
+
if (owner === undefined)
|
|
50
|
+
throw new SbError(`${file}: a sidebar is ${DOCS_DIR}/${SIDEBAR_FILE} or ${DOCS_DIR}/<ClassName>/${SIDEBAR_FILE}`);
|
|
51
|
+
const dir = owner ? `${DOCS_DIR}/${owner}` : DOCS_DIR;
|
|
52
|
+
const errors = [];
|
|
53
|
+
const listed = new Set();
|
|
54
|
+
const text = (value, at) => {
|
|
55
|
+
if (typeof value === 'string' && value.trim())
|
|
56
|
+
return value.trim();
|
|
57
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
58
|
+
const entries = Object.entries(value);
|
|
59
|
+
const bad = entries.filter(([lang, t]) => !isDocsLanguage(lang) || typeof t !== 'string' || !t.trim());
|
|
60
|
+
if (entries.length && !bad.length)
|
|
61
|
+
return Object.fromEntries(entries.map(([l, t]) => [l, t.trim()]));
|
|
62
|
+
}
|
|
63
|
+
errors.push(`${at}: text, or text by language ({ "tr": "...", "en": "..." })`);
|
|
64
|
+
};
|
|
65
|
+
const doc = (name, at) => {
|
|
66
|
+
if (typeof name !== 'string' || !name) {
|
|
67
|
+
errors.push(`${at}: a document's name, from where the sidebar is`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const parts = dir.split('/');
|
|
71
|
+
for (const part of name.split('/')) {
|
|
72
|
+
if (part === '..')
|
|
73
|
+
parts.pop();
|
|
74
|
+
else if (part && part !== '.')
|
|
75
|
+
parts.push(part);
|
|
76
|
+
}
|
|
77
|
+
const path = parts.join('/');
|
|
78
|
+
if (!path.startsWith(dir + '/') || (!owner && isModuleDoc(path))) {
|
|
79
|
+
errors.push(`${at}: "${name}" is not ${owner ? `${owner}'s` : "the package's own"} - a sidebar lists the documents beside it`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (!docs.has(path)) {
|
|
83
|
+
errors.push(`${at}: "${name}" is not a document of the package - named as in its own language, without one (network.md, not network.tr.md)`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (listed.has(path)) {
|
|
87
|
+
errors.push(`${at}: "${name}" is listed twice`);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
listed.add(path);
|
|
91
|
+
return path;
|
|
92
|
+
};
|
|
93
|
+
const items = (value, at, depth) => {
|
|
94
|
+
if (!Array.isArray(value)) {
|
|
95
|
+
errors.push(`${at}: a list of items`);
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
const out = [];
|
|
99
|
+
value.forEach((item, i) => {
|
|
100
|
+
const here = `${at}[${i}]`;
|
|
101
|
+
if (typeof item === 'string') {
|
|
102
|
+
const path = doc(item, here);
|
|
103
|
+
if (path)
|
|
104
|
+
out.push({ doc: path });
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (!item || typeof item !== 'object' || Array.isArray(item)) {
|
|
108
|
+
errors.push(`${here}: a document's name, or an object`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const keys = Object.keys(item);
|
|
112
|
+
if ('doc' in item) {
|
|
113
|
+
const unknown = keys.filter(k => k !== 'doc' && k !== 'title');
|
|
114
|
+
if (unknown.length)
|
|
115
|
+
errors.push(`${here}: "${unknown.join('", "')}" is not read`);
|
|
116
|
+
const path = doc(item.doc, `${here}.doc`);
|
|
117
|
+
const title = item.title === undefined
|
|
118
|
+
? undefined
|
|
119
|
+
: text(item.title, `${here}.title`);
|
|
120
|
+
if (path)
|
|
121
|
+
out.push(title ? { doc: path, title } : { doc: path });
|
|
122
|
+
}
|
|
123
|
+
else if ('label' in item) {
|
|
124
|
+
const unknown = keys.filter(k => k !== 'label' && k !== 'items');
|
|
125
|
+
if (unknown.length)
|
|
126
|
+
errors.push(`${here}: "${unknown.join('", "')}" is not read`);
|
|
127
|
+
if (depth >= MAX_DEPTH)
|
|
128
|
+
errors.push(`${here}: categories go ${MAX_DEPTH} deep at most`);
|
|
129
|
+
const label = text(item.label, `${here}.label`);
|
|
130
|
+
const inner = items(item.items, `${here}.items`, depth + 1);
|
|
131
|
+
if (label)
|
|
132
|
+
out.push({ label, items: inner });
|
|
133
|
+
}
|
|
134
|
+
else
|
|
135
|
+
errors.push(`${here}: a document ("doc") or a category ("label" and "items")`);
|
|
136
|
+
});
|
|
137
|
+
return out;
|
|
138
|
+
};
|
|
139
|
+
let result = [];
|
|
140
|
+
if (!source || typeof source !== 'object' || Array.isArray(source))
|
|
141
|
+
errors.push(`${file}: an object, its "items" listed`);
|
|
142
|
+
else {
|
|
143
|
+
const unknown = Object.keys(source).filter(k => k !== 'items');
|
|
144
|
+
if (unknown.length)
|
|
145
|
+
errors.push(`${file}: "${unknown.join('", "')}" is not read`);
|
|
146
|
+
result = items(source.items, `${file}: items`, 0);
|
|
147
|
+
}
|
|
148
|
+
if (errors.length)
|
|
149
|
+
throw new SbError(errors.join('\n'));
|
|
150
|
+
return { items: result };
|
|
151
|
+
}
|
|
152
|
+
/** A path in docs/ that is a module's: in docs/<ClassName>/ */
|
|
153
|
+
function isModuleDoc(path) {
|
|
154
|
+
const parts = path.split('/');
|
|
155
|
+
return parts.length > 2 && CLASS_DIR_PATTERN.test(parts[1]);
|
|
156
|
+
}
|
|
157
|
+
/** The documents a sidebar lists, by their paths */
|
|
158
|
+
export function sidebarDocs(sidebar) {
|
|
159
|
+
const out = [];
|
|
160
|
+
const walk = (items) => {
|
|
161
|
+
for (const item of items)
|
|
162
|
+
if ('doc' in item)
|
|
163
|
+
out.push(item.doc);
|
|
164
|
+
else
|
|
165
|
+
walk(item.items);
|
|
166
|
+
};
|
|
167
|
+
walk(sidebar.items);
|
|
168
|
+
return out;
|
|
169
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
2
|
import type { Type } from 'ts-gems';
|
|
3
|
+
import { AppBase } from '../classes/app-base.js';
|
|
3
4
|
import { BaseElement } from '../classes/base-element.js';
|
|
4
5
|
import { ComponentBase } from '../classes/component-base.js';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import type { ExtensionPackageJson } from './package-manifest.js';
|
|
6
|
+
import { AppMetadata, ComponentMetadata, ElementMetadata, PluginMetadata } from '../models/index.js';
|
|
7
|
+
import type { ExtensionPackageJson, SyncBridgeManifest } from './package-manifest.js';
|
|
8
8
|
/**
|
|
9
9
|
*
|
|
10
10
|
*/
|
|
@@ -19,23 +19,32 @@ export declare class ExtensionPackage {
|
|
|
19
19
|
/** What the package expects the host to provide */
|
|
20
20
|
peerDependencies: Record<string, string>;
|
|
21
21
|
components: ComponentExtension[];
|
|
22
|
-
|
|
22
|
+
apps: AppExtension[];
|
|
23
|
+
plugins: PluginExtension[];
|
|
23
24
|
errors: Error[];
|
|
25
|
+
/** What was passed over reading the package: fields of its manifest SyncBridge does not know */
|
|
26
|
+
warnings: string[];
|
|
24
27
|
/**
|
|
25
|
-
* Takes the package's identity and dependencies from its `package.json
|
|
28
|
+
* Takes the package's identity and dependencies from its `package.json`
|
|
29
|
+
* and its manifest (see readExtensionManifest)
|
|
26
30
|
*/
|
|
27
|
-
assignManifest(pkgJson: ExtensionPackageJson): void;
|
|
31
|
+
assignManifest(pkgJson: ExtensionPackageJson, manifest?: SyncBridgeManifest): void;
|
|
28
32
|
}
|
|
29
33
|
/**
|
|
30
34
|
*
|
|
31
35
|
*/
|
|
32
36
|
export declare abstract class ExtensionBase {
|
|
33
|
-
abstract readonly kind: 'component' | '
|
|
37
|
+
abstract readonly kind: 'component' | 'app';
|
|
34
38
|
protected _ctor?: Type;
|
|
35
39
|
readonly pkg: ExtensionPackage;
|
|
36
40
|
readonly exportName: string;
|
|
37
41
|
readonly metadata: ElementMetadata;
|
|
38
42
|
readonly className: string;
|
|
43
|
+
/**
|
|
44
|
+
* The module the class is exported from: its own, given in the manifest,
|
|
45
|
+
* or else the package's entry point
|
|
46
|
+
*/
|
|
47
|
+
entryPoint?: string;
|
|
39
48
|
protected constructor(pkg: ExtensionPackage, exportName: string, metadata: ElementMetadata, ctor?: Type<BaseElement>);
|
|
40
49
|
get uri(): string;
|
|
41
50
|
get displayName(): string;
|
|
@@ -54,10 +63,28 @@ export declare class ComponentExtension extends ExtensionBase {
|
|
|
54
63
|
/**
|
|
55
64
|
*
|
|
56
65
|
*/
|
|
57
|
-
export declare class
|
|
58
|
-
readonly kind = "
|
|
59
|
-
protected _ctor?: Type<
|
|
60
|
-
readonly metadata:
|
|
61
|
-
constructor(pkg: ExtensionPackage, exportName: string, metadata:
|
|
62
|
-
getClass(): Promise<Type<
|
|
66
|
+
export declare class AppExtension extends ExtensionBase {
|
|
67
|
+
readonly kind = "app";
|
|
68
|
+
protected _ctor?: Type<AppBase>;
|
|
69
|
+
readonly metadata: AppMetadata;
|
|
70
|
+
constructor(pkg: ExtensionPackage, exportName: string, metadata: AppMetadata, ctor?: Type<AppBase>);
|
|
71
|
+
getClass(): Promise<Type<AppBase>>;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* A plugin a package brings: it extends SyncBridge itself, loaded in the
|
|
75
|
+
* engine's main process, never in a worker
|
|
76
|
+
*/
|
|
77
|
+
export declare class PluginExtension {
|
|
78
|
+
readonly pkg: ExtensionPackage;
|
|
79
|
+
readonly exportName: string;
|
|
80
|
+
readonly metadata: PluginMetadata;
|
|
81
|
+
readonly kind = "plugin";
|
|
82
|
+
protected _ctor?: Type;
|
|
83
|
+
/** The module the class is exported from */
|
|
84
|
+
entryPoint?: string;
|
|
85
|
+
constructor(pkg: ExtensionPackage, exportName: string, metadata: PluginMetadata, ctor?: Type);
|
|
86
|
+
/** The name it is set by: `plugins.<name>` */
|
|
87
|
+
get name(): string;
|
|
88
|
+
get version(): string;
|
|
89
|
+
getClass(): Promise<Type>;
|
|
63
90
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
|
+
import { AppBase } from '../classes/app-base.js';
|
|
2
3
|
import { BaseElement } from '../classes/base-element.js';
|
|
3
4
|
import { ComponentBase } from '../classes/component-base.js';
|
|
4
|
-
import { ProcessorBase } from '../classes/processor-base.js';
|
|
5
5
|
import { SbError } from '../classes/sb-error.js';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { CLASS_TYPE } from '../constants.js';
|
|
7
|
+
import { AppMetadata, ComponentMetadata, ElementMetadata, PluginMetadata, } from '../models/index.js';
|
|
8
|
+
import { isAppBase, isComponentBase } from '../utils/type-guards.js';
|
|
8
9
|
/**
|
|
9
10
|
*
|
|
10
11
|
*/
|
|
@@ -14,16 +15,20 @@ export class ExtensionPackage {
|
|
|
14
15
|
/** What the package expects the host to provide */
|
|
15
16
|
peerDependencies = {};
|
|
16
17
|
components = [];
|
|
17
|
-
|
|
18
|
+
apps = [];
|
|
19
|
+
plugins = [];
|
|
18
20
|
errors = [];
|
|
21
|
+
/** What was passed over reading the package: fields of its manifest SyncBridge does not know */
|
|
22
|
+
warnings = [];
|
|
19
23
|
/**
|
|
20
|
-
* Takes the package's identity and dependencies from its `package.json
|
|
24
|
+
* Takes the package's identity and dependencies from its `package.json`
|
|
25
|
+
* and its manifest (see readExtensionManifest)
|
|
21
26
|
*/
|
|
22
|
-
assignManifest(pkgJson) {
|
|
23
|
-
this.name =
|
|
27
|
+
assignManifest(pkgJson, manifest) {
|
|
28
|
+
this.name = manifest?.name || pkgJson.name;
|
|
24
29
|
this.version = pkgJson.version;
|
|
25
30
|
this.description = pkgJson.description;
|
|
26
|
-
this.registryDependencies = { ...
|
|
31
|
+
this.registryDependencies = { ...manifest?.dependencies };
|
|
27
32
|
this.peerDependencies = { ...pkgJson.peerDependencies };
|
|
28
33
|
}
|
|
29
34
|
}
|
|
@@ -66,7 +71,7 @@ export class ComponentExtension extends ExtensionBase {
|
|
|
66
71
|
async getClass() {
|
|
67
72
|
if (this._ctor)
|
|
68
73
|
return this._ctor;
|
|
69
|
-
const module = await import(this.pkg.entryPoint);
|
|
74
|
+
const module = await import(this.entryPoint || this.pkg.entryPoint);
|
|
70
75
|
const ctor = module[this.exportName];
|
|
71
76
|
if (!ctor)
|
|
72
77
|
throw new SbError(`Exported component "${this.exportName}" not found in package "${this.pkg.name}"`);
|
|
@@ -81,26 +86,61 @@ export class ComponentExtension extends ExtensionBase {
|
|
|
81
86
|
/**
|
|
82
87
|
*
|
|
83
88
|
*/
|
|
84
|
-
export class
|
|
85
|
-
kind = '
|
|
89
|
+
export class AppExtension extends ExtensionBase {
|
|
90
|
+
kind = 'app';
|
|
86
91
|
constructor(pkg, exportName, metadata, ctor) {
|
|
87
92
|
super(pkg, exportName, metadata, ctor);
|
|
88
|
-
if (ctor && !
|
|
89
|
-
throw new SbError(`${ctor.name} does not extends
|
|
93
|
+
if (ctor && !isAppBase(ctor.prototype))
|
|
94
|
+
throw new SbError(`${ctor.name} does not extends AppBase`);
|
|
90
95
|
}
|
|
91
96
|
async getClass() {
|
|
92
97
|
if (this._ctor)
|
|
93
98
|
return this._ctor;
|
|
94
|
-
const module = await import(this.pkg.entryPoint);
|
|
99
|
+
const module = await import(this.entryPoint || this.pkg.entryPoint);
|
|
95
100
|
const ctor = module[this.exportName];
|
|
96
101
|
if (!ctor)
|
|
97
|
-
throw new SbError(`Exported
|
|
102
|
+
throw new SbError(`Exported app "${this.exportName}" not found in package "${this.pkg.name}"`);
|
|
98
103
|
if (typeof ctor !== 'function')
|
|
99
|
-
throw new SbError(`Exported
|
|
100
|
-
if (!
|
|
101
|
-
throw new SbError(`Exported
|
|
104
|
+
throw new SbError(`Exported app "${this.exportName}" is not a class`);
|
|
105
|
+
if (!isAppBase(ctor.prototype))
|
|
106
|
+
throw new SbError(`Exported app "${this.exportName}" does not extends AppBase`);
|
|
102
107
|
this._ctor = ctor;
|
|
103
108
|
return this._ctor;
|
|
104
109
|
}
|
|
105
110
|
}
|
|
106
|
-
|
|
111
|
+
/**
|
|
112
|
+
* A plugin a package brings: it extends SyncBridge itself, loaded in the
|
|
113
|
+
* engine's main process, never in a worker
|
|
114
|
+
*/
|
|
115
|
+
export class PluginExtension {
|
|
116
|
+
pkg;
|
|
117
|
+
exportName;
|
|
118
|
+
metadata;
|
|
119
|
+
kind = 'plugin';
|
|
120
|
+
_ctor;
|
|
121
|
+
constructor(pkg, exportName, metadata, ctor) {
|
|
122
|
+
this.pkg = pkg;
|
|
123
|
+
this.exportName = exportName;
|
|
124
|
+
this.metadata = metadata;
|
|
125
|
+
this._ctor = ctor;
|
|
126
|
+
}
|
|
127
|
+
/** The name it is set by: `plugins.<name>` */
|
|
128
|
+
get name() {
|
|
129
|
+
return this.metadata.name;
|
|
130
|
+
}
|
|
131
|
+
get version() {
|
|
132
|
+
return this.pkg.version;
|
|
133
|
+
}
|
|
134
|
+
async getClass() {
|
|
135
|
+
if (this._ctor)
|
|
136
|
+
return this._ctor;
|
|
137
|
+
const module = await import(this.entryPoint || this.pkg.entryPoint);
|
|
138
|
+
const ctor = module[this.exportName];
|
|
139
|
+
if (typeof ctor !== 'function')
|
|
140
|
+
throw new SbError(`Exported plugin "${this.exportName}" not found in package "${this.pkg.name}"`);
|
|
141
|
+
if (Reflect.getMetadata(CLASS_TYPE, ctor) !== 'plugin')
|
|
142
|
+
throw new SbError(`Exported plugin "${this.exportName}" is not decorated with @Plugin`);
|
|
143
|
+
this._ctor = ctor;
|
|
144
|
+
return ctor;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { ResponsiveMap } from '@opra/common';
|
|
2
2
|
import { AsyncEventEmitter } from 'node-events-async';
|
|
3
3
|
import type { Type } from 'ts-gems';
|
|
4
|
+
import { AppBase } from '../classes/app-base.js';
|
|
4
5
|
import { ComponentBase } from '../classes/component-base.js';
|
|
5
|
-
import {
|
|
6
|
-
import { ComponentExtension, ExtensionPackage, ProcessorExtension } from './extension-package.js';
|
|
6
|
+
import { AppExtension, ComponentExtension, ExtensionPackage } from './extension-package.js';
|
|
7
7
|
declare const instanceSymbol: unique symbol;
|
|
8
8
|
/**
|
|
9
|
-
* The `ExtensionRegistry` class is responsible for managing component and
|
|
9
|
+
* The `ExtensionRegistry` class is responsible for managing component and app extensions,
|
|
10
10
|
* as well as handling the registration of extension packages. It provides methods to locate and
|
|
11
11
|
* retrieve extensions by their class name and version, and offers the ability to dynamically register
|
|
12
|
-
* packages, components, and
|
|
12
|
+
* packages, components, and apps at runtime.
|
|
13
13
|
*
|
|
14
14
|
* @class ExtensionRegistry
|
|
15
15
|
*/
|
|
@@ -22,7 +22,7 @@ export declare class ExtensionRegistry extends AsyncEventEmitter {
|
|
|
22
22
|
registry: ExtensionRegistry;
|
|
23
23
|
}[];
|
|
24
24
|
/**
|
|
25
|
-
* The registry the static methods act on, and so
|
|
25
|
+
* The registry the static methods act on, and so AppFactory and
|
|
26
26
|
* the metadata helpers: the process's own, unless another is in use.
|
|
27
27
|
*/
|
|
28
28
|
static get current(): ExtensionRegistry;
|
|
@@ -37,27 +37,27 @@ export declare class ExtensionRegistry extends AsyncEventEmitter {
|
|
|
37
37
|
static get packages(): ResponsiveMap<ExtensionPackage[]>;
|
|
38
38
|
static get components(): ResponsiveMap<ComponentExtension[]>;
|
|
39
39
|
static get componentsByClassName(): ResponsiveMap<ComponentExtension[]>;
|
|
40
|
-
static get
|
|
41
|
-
static get
|
|
40
|
+
static get apps(): ResponsiveMap<AppExtension[]>;
|
|
41
|
+
static get appsByClassName(): ResponsiveMap<AppExtension[]>;
|
|
42
42
|
static setResolver(fn: ExtensionRegistry.PackageResolver | undefined): void;
|
|
43
43
|
static findComponent(uri: string, version?: string): ComponentExtension | undefined;
|
|
44
44
|
static getComponent(uri: string, version?: string): ComponentExtension;
|
|
45
|
-
static
|
|
46
|
-
static
|
|
45
|
+
static findApp(uri: string, version?: string): AppExtension | undefined;
|
|
46
|
+
static getApp(uri: string, version?: string): AppExtension;
|
|
47
47
|
static registerPackage(specifier: string): Promise<ExtensionPackage>;
|
|
48
48
|
static registerClass<T extends ComponentBase>(ctor: Type<T>): Promise<ComponentExtension>;
|
|
49
|
-
static registerClass<T extends
|
|
49
|
+
static registerClass<T extends AppBase>(ctor: Type<T>): Promise<AppExtension>;
|
|
50
50
|
static storePackage(pkg: ExtensionPackage): void;
|
|
51
51
|
static onRegisterPackage(fn: (pkg: ExtensionPackage) => void): void;
|
|
52
52
|
static onRegisterComponent(fn: (pkg: ComponentExtension) => void): void;
|
|
53
|
-
static
|
|
53
|
+
static onRegisterApp(fn: (pkg: AppExtension) => void): void;
|
|
54
54
|
constructor();
|
|
55
55
|
protected _resolver: ExtensionRegistry.PackageResolver;
|
|
56
56
|
readonly packages: ResponsiveMap<ExtensionPackage[]>;
|
|
57
57
|
readonly components: ResponsiveMap<ComponentExtension[]>;
|
|
58
58
|
readonly componentsByClassName: ResponsiveMap<ComponentExtension[]>;
|
|
59
|
-
readonly
|
|
60
|
-
readonly
|
|
59
|
+
readonly apps: ResponsiveMap<AppExtension[]>;
|
|
60
|
+
readonly appsByClassName: ResponsiveMap<AppExtension[]>;
|
|
61
61
|
/**
|
|
62
62
|
*
|
|
63
63
|
*/
|
|
@@ -73,17 +73,17 @@ export declare class ExtensionRegistry extends AsyncEventEmitter {
|
|
|
73
73
|
/**
|
|
74
74
|
*
|
|
75
75
|
*/
|
|
76
|
-
|
|
76
|
+
findApp(uri: string, version?: string): AppExtension | undefined;
|
|
77
77
|
/**
|
|
78
78
|
*
|
|
79
79
|
*/
|
|
80
|
-
|
|
80
|
+
getApp(uri: string, version?: string): AppExtension;
|
|
81
81
|
/**
|
|
82
82
|
*
|
|
83
83
|
*/
|
|
84
84
|
registerPackage(specifier: string): Promise<ExtensionPackage>;
|
|
85
85
|
registerClass<T extends ComponentBase>(ctor: Type<T>): Promise<ComponentExtension>;
|
|
86
|
-
registerClass<T extends
|
|
86
|
+
registerClass<T extends AppBase>(ctor: Type<T>): Promise<AppExtension>;
|
|
87
87
|
/**
|
|
88
88
|
*
|
|
89
89
|
*/
|