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.
Files changed (53) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +248 -0
  3. package/bin/cli.js +433 -0
  4. package/package.json +63 -0
  5. package/src/builder/context-resolver.js +62 -0
  6. package/src/builder/dependency-graph-cache.js +105 -0
  7. package/src/builder/dependency-graph.js +141 -0
  8. package/src/builder/facet-validator.js +43 -0
  9. package/src/builder/hook-processor.js +271 -0
  10. package/src/builder/index.js +13 -0
  11. package/src/builder/subsystem-builder.js +104 -0
  12. package/src/builder/utils.js +165 -0
  13. package/src/contract/contracts/hierarchy.contract.js +60 -0
  14. package/src/contract/contracts/index.js +17 -0
  15. package/src/contract/contracts/listeners.contract.js +66 -0
  16. package/src/contract/contracts/processor.contract.js +47 -0
  17. package/src/contract/contracts/queue.contract.js +58 -0
  18. package/src/contract/contracts/router.contract.js +53 -0
  19. package/src/contract/contracts/scheduler.contract.js +65 -0
  20. package/src/contract/contracts/server.contract.js +88 -0
  21. package/src/contract/contracts/speak.contract.js +50 -0
  22. package/src/contract/contracts/storage.contract.js +107 -0
  23. package/src/contract/contracts/websocket.contract.js +90 -0
  24. package/src/contract/facet-contract-registry.js +155 -0
  25. package/src/contract/facet-contract.js +136 -0
  26. package/src/contract/index.js +63 -0
  27. package/src/core/create-hook.js +63 -0
  28. package/src/core/facet.js +189 -0
  29. package/src/core/index.js +3 -0
  30. package/src/hooks/listeners/handler-group-manager.js +88 -0
  31. package/src/hooks/listeners/listener-manager-policies.js +229 -0
  32. package/src/hooks/listeners/listener-manager.js +668 -0
  33. package/src/hooks/listeners/listener-registry.js +176 -0
  34. package/src/hooks/listeners/listener-statistics.js +106 -0
  35. package/src/hooks/listeners/pattern-matcher.js +283 -0
  36. package/src/hooks/listeners/use-listeners.js +164 -0
  37. package/src/hooks/queue/bounded-queue.js +341 -0
  38. package/src/hooks/queue/circular-buffer.js +231 -0
  39. package/src/hooks/queue/subsystem-queue-manager.js +198 -0
  40. package/src/hooks/queue/use-queue.js +96 -0
  41. package/src/hooks/speak/use-speak.js +79 -0
  42. package/src/index.js +49 -0
  43. package/src/manager/facet-manager-transaction.js +45 -0
  44. package/src/manager/facet-manager.js +570 -0
  45. package/src/manager/index.js +3 -0
  46. package/src/system/base-subsystem.js +416 -0
  47. package/src/system/base-subsystem.utils.js +106 -0
  48. package/src/system/index.js +4 -0
  49. package/src/system/standalone-plugin-system.js +70 -0
  50. package/src/utils/debug-flag.js +34 -0
  51. package/src/utils/find-facet.js +30 -0
  52. package/src/utils/logger.js +84 -0
  53. 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
+