mycelia-kernel-plugin 1.0.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/LICENSE +22 -0
- package/README.md +248 -0
- package/bin/cli.js +433 -0
- package/package.json +63 -0
- package/src/builder/context-resolver.js +62 -0
- package/src/builder/dependency-graph-cache.js +105 -0
- package/src/builder/dependency-graph.js +141 -0
- package/src/builder/facet-validator.js +43 -0
- package/src/builder/hook-processor.js +271 -0
- package/src/builder/index.js +13 -0
- package/src/builder/subsystem-builder.js +104 -0
- package/src/builder/utils.js +165 -0
- package/src/contract/contracts/hierarchy.contract.js +60 -0
- package/src/contract/contracts/index.js +17 -0
- package/src/contract/contracts/listeners.contract.js +66 -0
- package/src/contract/contracts/processor.contract.js +47 -0
- package/src/contract/contracts/queue.contract.js +58 -0
- package/src/contract/contracts/router.contract.js +53 -0
- package/src/contract/contracts/scheduler.contract.js +65 -0
- package/src/contract/contracts/server.contract.js +88 -0
- package/src/contract/contracts/speak.contract.js +50 -0
- package/src/contract/contracts/storage.contract.js +107 -0
- package/src/contract/contracts/websocket.contract.js +90 -0
- package/src/contract/facet-contract-registry.js +155 -0
- package/src/contract/facet-contract.js +136 -0
- package/src/contract/index.js +63 -0
- package/src/core/create-hook.js +63 -0
- package/src/core/facet.js +189 -0
- package/src/core/index.js +3 -0
- package/src/hooks/listeners/handler-group-manager.js +88 -0
- package/src/hooks/listeners/listener-manager-policies.js +229 -0
- package/src/hooks/listeners/listener-manager.js +668 -0
- package/src/hooks/listeners/listener-registry.js +176 -0
- package/src/hooks/listeners/listener-statistics.js +106 -0
- package/src/hooks/listeners/pattern-matcher.js +283 -0
- package/src/hooks/listeners/use-listeners.js +164 -0
- package/src/hooks/queue/bounded-queue.js +341 -0
- package/src/hooks/queue/circular-buffer.js +231 -0
- package/src/hooks/queue/subsystem-queue-manager.js +198 -0
- package/src/hooks/queue/use-queue.js +96 -0
- package/src/hooks/speak/use-speak.js +79 -0
- package/src/index.js +49 -0
- package/src/manager/facet-manager-transaction.js +45 -0
- package/src/manager/facet-manager.js +570 -0
- package/src/manager/index.js +3 -0
- package/src/system/base-subsystem.js +416 -0
- package/src/system/base-subsystem.utils.js +106 -0
- package/src/system/index.js +4 -0
- package/src/system/standalone-plugin-system.js +70 -0
- package/src/utils/debug-flag.js +34 -0
- package/src/utils/find-facet.js +30 -0
- package/src/utils/logger.js +84 -0
- package/src/utils/semver.js +221 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides a simple logger abstraction for improved testability and consistency.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Simple logger that conditionally logs based on debug flag.
|
|
9
|
+
*
|
|
10
|
+
* @param {boolean} debug - Whether debug logging is enabled
|
|
11
|
+
* @param {string} prefix - Optional prefix for log messages (e.g., subsystem name)
|
|
12
|
+
* @returns {Object} Logger object with log, error, warn methods
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```javascript
|
|
16
|
+
* const logger = createLogger(debug, subsystem.name);
|
|
17
|
+
* logger.log('System initialized');
|
|
18
|
+
* logger.error('Failed to initialize', error);
|
|
19
|
+
* logger.warn('Deprecated feature used');
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export function createLogger(debug = false, prefix = '') {
|
|
23
|
+
const prefixStr = prefix ? `[${prefix}] ` : '';
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
/**
|
|
27
|
+
* Log an info message (only if debug is enabled)
|
|
28
|
+
* @param {...any} args - Arguments to log
|
|
29
|
+
*/
|
|
30
|
+
log(...args) {
|
|
31
|
+
if (debug) {
|
|
32
|
+
console.log(prefixStr, ...args);
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Log an error message (always logged, but with prefix only if debug is enabled)
|
|
38
|
+
* @param {...any} args - Arguments to log
|
|
39
|
+
*/
|
|
40
|
+
error(...args) {
|
|
41
|
+
if (debug) {
|
|
42
|
+
console.error(prefixStr, ...args);
|
|
43
|
+
} else {
|
|
44
|
+
// Still log errors even if debug is off, but without prefix
|
|
45
|
+
console.error(...args);
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Log a warning message (only if debug is enabled)
|
|
51
|
+
* @param {...any} args - Arguments to log
|
|
52
|
+
*/
|
|
53
|
+
warn(...args) {
|
|
54
|
+
if (debug) {
|
|
55
|
+
console.warn(prefixStr, ...args);
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Check if debug logging is enabled
|
|
61
|
+
* @returns {boolean} True if debug is enabled
|
|
62
|
+
*/
|
|
63
|
+
isDebugEnabled() {
|
|
64
|
+
return debug;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Create a logger for a subsystem
|
|
71
|
+
*
|
|
72
|
+
* @param {BaseSubsystem} subsystem - Subsystem instance
|
|
73
|
+
* @returns {Object} Logger object
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```javascript
|
|
77
|
+
* const logger = createSubsystemLogger(subsystem);
|
|
78
|
+
* logger.log('Built successfully');
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export function createSubsystemLogger(subsystem) {
|
|
82
|
+
return createLogger(subsystem?.debug || false, subsystem?.name || '');
|
|
83
|
+
}
|
|
84
|
+
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic Versioning (Semver) Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides validation and comparison for semantic version strings.
|
|
5
|
+
* Supports semver 2.0.0 specification with simplified ranges.
|
|
6
|
+
*
|
|
7
|
+
* Supported version formats:
|
|
8
|
+
* - '1.0.0' - Exact version
|
|
9
|
+
* - '^1.0.0' - Compatible with version (>=1.0.0 <2.0.0)
|
|
10
|
+
* - '~1.0.0' - Approximately equivalent (>=1.0.0 <1.1.0)
|
|
11
|
+
* - '>=1.0.0' - Greater than or equal
|
|
12
|
+
* - '>1.0.0' - Greater than
|
|
13
|
+
* - '<=1.0.0' - Less than or equal
|
|
14
|
+
* - '<1.0.0' - Less than
|
|
15
|
+
* - '*' - Any version
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const SEMVER_REGEX = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/;
|
|
19
|
+
const RANGE_REGEX = /^([\^~><=*]*)(.*)$/;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Parse a semver string into components
|
|
23
|
+
*
|
|
24
|
+
* @param {string} version - Version string (e.g., '1.2.3-alpha.1+build.123')
|
|
25
|
+
* @returns {Object|null} Parsed version or null if invalid
|
|
26
|
+
* @returns {number} result.major - Major version number
|
|
27
|
+
* @returns {number} result.minor - Minor version number
|
|
28
|
+
* @returns {number} result.patch - Patch version number
|
|
29
|
+
* @returns {string} result.prerelease - Prerelease identifier (e.g., 'alpha.1')
|
|
30
|
+
* @returns {string} result.build - Build metadata (e.g., 'build.123')
|
|
31
|
+
* @returns {string} result.raw - Original version string
|
|
32
|
+
*/
|
|
33
|
+
export function parseVersion(version) {
|
|
34
|
+
if (typeof version !== 'string') {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const match = version.match(SEMVER_REGEX);
|
|
39
|
+
if (!match) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
major: parseInt(match[1], 10),
|
|
45
|
+
minor: parseInt(match[2], 10),
|
|
46
|
+
patch: parseInt(match[3], 10),
|
|
47
|
+
prerelease: match[4] || '',
|
|
48
|
+
build: match[5] || '',
|
|
49
|
+
raw: version
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Check if a string is a valid semver version
|
|
55
|
+
*
|
|
56
|
+
* @param {string} version - Version string to validate
|
|
57
|
+
* @returns {boolean} True if valid semver
|
|
58
|
+
*/
|
|
59
|
+
export function isValidSemver(version) {
|
|
60
|
+
return parseVersion(version) !== null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Compare two semver versions
|
|
65
|
+
*
|
|
66
|
+
* @param {string} v1 - First version
|
|
67
|
+
* @param {string} v2 - Second version
|
|
68
|
+
* @returns {number} -1 if v1 < v2, 0 if v1 === v2, 1 if v1 > v2
|
|
69
|
+
* @throws {Error} If either version is invalid
|
|
70
|
+
*/
|
|
71
|
+
export function compareVersions(v1, v2) {
|
|
72
|
+
const parsed1 = parseVersion(v1);
|
|
73
|
+
const parsed2 = parseVersion(v2);
|
|
74
|
+
|
|
75
|
+
if (!parsed1) {
|
|
76
|
+
throw new Error(`Invalid semver: ${v1}`);
|
|
77
|
+
}
|
|
78
|
+
if (!parsed2) {
|
|
79
|
+
throw new Error(`Invalid semver: ${v2}`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Compare major
|
|
83
|
+
if (parsed1.major !== parsed2.major) {
|
|
84
|
+
return parsed1.major < parsed2.major ? -1 : 1;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Compare minor
|
|
88
|
+
if (parsed1.minor !== parsed2.minor) {
|
|
89
|
+
return parsed1.minor < parsed2.minor ? -1 : 1;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Compare patch
|
|
93
|
+
if (parsed1.patch !== parsed2.patch) {
|
|
94
|
+
return parsed1.patch < parsed2.patch ? -1 : 1;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Compare prerelease (versions without prerelease are greater)
|
|
98
|
+
if (parsed1.prerelease !== parsed2.prerelease) {
|
|
99
|
+
if (!parsed1.prerelease) return 1;
|
|
100
|
+
if (!parsed2.prerelease) return -1;
|
|
101
|
+
return parsed1.prerelease < parsed2.prerelease ? -1 : 1;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Check if version satisfies a range
|
|
109
|
+
*
|
|
110
|
+
* Supported ranges:
|
|
111
|
+
* - '1.0.0' - Exact match
|
|
112
|
+
* - '^1.0.0' - Compatible (>=1.0.0 <2.0.0)
|
|
113
|
+
* - '~1.0.0' - Approximately (>=1.0.0 <1.1.0)
|
|
114
|
+
* - '>=1.0.0', '>1.0.0', '<=1.0.0', '<1.0.0' - Comparisons
|
|
115
|
+
* - '*' - Any version
|
|
116
|
+
*
|
|
117
|
+
* @param {string} version - Version to check
|
|
118
|
+
* @param {string} range - Range specification
|
|
119
|
+
* @returns {boolean} True if version satisfies range
|
|
120
|
+
* @throws {Error} If version or range is invalid
|
|
121
|
+
*/
|
|
122
|
+
export function satisfiesRange(version, range) {
|
|
123
|
+
if (typeof range !== 'string') {
|
|
124
|
+
throw new Error('Range must be a string');
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Wildcard matches any version
|
|
128
|
+
if (range === '*') {
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const versionParsed = parseVersion(version);
|
|
133
|
+
if (!versionParsed) {
|
|
134
|
+
throw new Error(`Invalid semver: ${version}`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const match = range.match(RANGE_REGEX);
|
|
138
|
+
if (!match) {
|
|
139
|
+
throw new Error(`Invalid range: ${range}`);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const operator = match[1] || '';
|
|
143
|
+
const targetVersion = match[2].trim();
|
|
144
|
+
|
|
145
|
+
const targetParsed = parseVersion(targetVersion);
|
|
146
|
+
if (!targetParsed) {
|
|
147
|
+
throw new Error(`Invalid semver in range: ${targetVersion}`);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Caret range: ^1.2.3 means >=1.2.3 <2.0.0
|
|
151
|
+
if (operator === '^') {
|
|
152
|
+
return (
|
|
153
|
+
versionParsed.major === targetParsed.major &&
|
|
154
|
+
compareVersions(version, targetVersion) >= 0
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Tilde range: ~1.2.3 means >=1.2.3 <1.3.0
|
|
159
|
+
if (operator === '~') {
|
|
160
|
+
return (
|
|
161
|
+
versionParsed.major === targetParsed.major &&
|
|
162
|
+
versionParsed.minor === targetParsed.minor &&
|
|
163
|
+
compareVersions(version, targetVersion) >= 0
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Greater than or equal
|
|
168
|
+
if (operator === '>=') {
|
|
169
|
+
return compareVersions(version, targetVersion) >= 0;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Greater than
|
|
173
|
+
if (operator === '>') {
|
|
174
|
+
return compareVersions(version, targetVersion) > 0;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Less than or equal
|
|
178
|
+
if (operator === '<=') {
|
|
179
|
+
return compareVersions(version, targetVersion) <= 0;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Less than
|
|
183
|
+
if (operator === '<') {
|
|
184
|
+
return compareVersions(version, targetVersion) < 0;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Exact match (no operator)
|
|
188
|
+
if (operator === '') {
|
|
189
|
+
return compareVersions(version, targetVersion) === 0;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
throw new Error(`Unsupported range operator: ${operator}`);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Get the default version (0.0.0)
|
|
197
|
+
*
|
|
198
|
+
* @returns {string} Default version string
|
|
199
|
+
*/
|
|
200
|
+
export function getDefaultVersion() {
|
|
201
|
+
return '0.0.0';
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Validate that a version string is a valid semver
|
|
206
|
+
* Throws an error with a helpful message if invalid
|
|
207
|
+
*
|
|
208
|
+
* @param {string} version - Version string to validate
|
|
209
|
+
* @param {string} [context=''] - Context for error message (e.g., 'hook useRouter')
|
|
210
|
+
* @throws {Error} If version is invalid
|
|
211
|
+
*/
|
|
212
|
+
export function validateVersion(version, context = '') {
|
|
213
|
+
if (!isValidSemver(version)) {
|
|
214
|
+
const prefix = context ? `${context}: ` : '';
|
|
215
|
+
throw new Error(
|
|
216
|
+
`${prefix}Invalid semver version "${version}". ` +
|
|
217
|
+
'Must follow format: MAJOR.MINOR.PATCH (e.g., "1.0.0", "2.1.3-alpha")'
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|