@ultrst-armada/krnl 1.0.0 → 1.0.2
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 +35 -24
- package/package.json +12 -12
- package/packages/cli/dist/bin/krnl.cjs +1026 -9462
- package/packages/cli/dist/bin/krnl.js +14 -1859
- package/packages/cli/dist/chunk-ESTKOQ7T.js +1146 -0
- package/packages/cli/dist/chunk-FZ6X7PHR.js +1146 -0
- package/packages/cli/dist/index.cjs +735 -7348
- package/packages/cli/dist/index.js +1 -20
- package/packages/cli/package.json +2 -2
- package/packages/core/dist/index.cjs +140 -5
- package/packages/core/dist/index.d.cts +24 -2
- package/packages/core/dist/index.d.ts +24 -2
- package/packages/core/dist/index.js +137 -3
- package/packages/core/package.json +2 -2
- package/packages/create-krnl/dist/index.cjs +277 -308
- package/packages/create-krnl/dist/index.js +277 -308
- package/packages/create-krnl/package.json +2 -2
- package/packages/eslint-plugin/package.json +2 -2
- package/packages/validate/dist/index.cjs +407 -369
- package/packages/validate/dist/index.d.cts +1 -13
- package/packages/validate/dist/index.d.ts +1 -13
- package/packages/validate/dist/index.js +408 -370
- package/packages/validate/package.json +2 -2
|
@@ -2,26 +2,7 @@ import {
|
|
|
2
2
|
generateMagneticDeclarations,
|
|
3
3
|
runGenerate,
|
|
4
4
|
runValidate
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-RJNYUXZD.js";
|
|
7
|
-
import "./chunk-BOXWWXQG.js";
|
|
8
|
-
import "./chunk-OHVMVRBP.js";
|
|
9
|
-
import "./chunk-EG7T2IAD.js";
|
|
10
|
-
import "./chunk-SRTOPJ5W.js";
|
|
11
|
-
import "./chunk-6NIKAMUZ.js";
|
|
12
|
-
import "./chunk-P2PCLEKX.js";
|
|
13
|
-
import "./chunk-FDNCADFE.js";
|
|
14
|
-
import "./chunk-PJQIUOX2.js";
|
|
15
|
-
import "./chunk-GDLRMDAN.js";
|
|
16
|
-
import "./chunk-I74QIQOD.js";
|
|
17
|
-
import "./chunk-ZAAV3JXQ.js";
|
|
18
|
-
import "./chunk-5JDK35TG.js";
|
|
19
|
-
import "./chunk-Q45257P6.js";
|
|
20
|
-
import "./chunk-3TRM6CYL.js";
|
|
21
|
-
import "./chunk-XIRFOO3H.js";
|
|
22
|
-
import "./chunk-JTLSTO25.js";
|
|
23
|
-
import "./chunk-JULBBJ27.js";
|
|
24
|
-
import "./chunk-X5LOIFM7.js";
|
|
5
|
+
} from "./chunk-ESTKOQ7T.js";
|
|
25
6
|
export {
|
|
26
7
|
generateMagneticDeclarations,
|
|
27
8
|
runGenerate,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dinilmusick/krnl-cli",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Unified CLI for the Krnl Framework",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Unified CLI for the Krnl Backend Service Framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
HttpProtocolAdapter: () => HttpProtocolAdapter,
|
|
34
|
+
KrnlPackageReconciler: () => KrnlPackageReconciler,
|
|
34
35
|
LifecycleManager: () => LifecycleManager,
|
|
35
36
|
MemoryTransport: () => MemoryTransport,
|
|
36
37
|
P2PProtocolAdapter: () => P2PProtocolAdapter,
|
|
@@ -382,8 +383,6 @@ var HttpProtocolAdapter = class {
|
|
|
382
383
|
};
|
|
383
384
|
|
|
384
385
|
// src/protocols/WebSocketProtocolAdapter.ts
|
|
385
|
-
var import_http2 = __toESM(require("http"), 1);
|
|
386
|
-
var import_ws = require("ws");
|
|
387
386
|
var WebSocketProtocolAdapter = class {
|
|
388
387
|
protocol = "ws";
|
|
389
388
|
capabilities = {
|
|
@@ -399,8 +398,15 @@ var WebSocketProtocolAdapter = class {
|
|
|
399
398
|
wss;
|
|
400
399
|
port;
|
|
401
400
|
async expose(service, port = 0) {
|
|
402
|
-
|
|
403
|
-
|
|
401
|
+
const httpMod = await import("http");
|
|
402
|
+
const http2 = httpMod.default || httpMod;
|
|
403
|
+
const wsMod = await import("ws").catch(() => null);
|
|
404
|
+
if (!wsMod) {
|
|
405
|
+
throw new Error('WebSocketProtocolAdapter.expose requires "ws" package in Node.js environment.');
|
|
406
|
+
}
|
|
407
|
+
const WebSocketServer = wsMod.WebSocketServer || wsMod.default?.WebSocketServer || wsMod.Server;
|
|
408
|
+
this.server = http2.createServer();
|
|
409
|
+
this.wss = new WebSocketServer({ server: this.server });
|
|
404
410
|
this.wss.on("connection", (ws) => {
|
|
405
411
|
ws.on("message", async (raw) => {
|
|
406
412
|
try {
|
|
@@ -445,8 +451,16 @@ var WebSocketProtocolAdapter = class {
|
|
|
445
451
|
};
|
|
446
452
|
}
|
|
447
453
|
async send(endpoint, envelope) {
|
|
454
|
+
let WS = globalThis.WebSocket;
|
|
455
|
+
if (!WS) {
|
|
456
|
+
const wsMod = await import("ws").catch(() => null);
|
|
457
|
+
WS = wsMod?.WebSocket || wsMod?.default?.WebSocket || wsMod;
|
|
458
|
+
}
|
|
459
|
+
if (!WS) {
|
|
460
|
+
throw new Error("No WebSocket client implementation available in this environment.");
|
|
461
|
+
}
|
|
448
462
|
return new Promise((resolve, reject) => {
|
|
449
|
-
const ws = new
|
|
463
|
+
const ws = new WS(`ws://${endpoint.address}:${endpoint.port}`);
|
|
450
464
|
ws.on("open", () => {
|
|
451
465
|
ws.send(JSON.stringify(envelope));
|
|
452
466
|
});
|
|
@@ -724,6 +738,126 @@ var ServiceDiscovery = class {
|
|
|
724
738
|
}
|
|
725
739
|
};
|
|
726
740
|
|
|
741
|
+
// src/discovery/KrnlPackageReconciler.ts
|
|
742
|
+
var fs = __toESM(require("fs"), 1);
|
|
743
|
+
var path = __toESM(require("path"), 1);
|
|
744
|
+
var KrnlPackageReconciler = class {
|
|
745
|
+
/**
|
|
746
|
+
* Scans all manifest.json files across backend and frontend and reconciles root package.json.
|
|
747
|
+
*/
|
|
748
|
+
static reconcile(projectRoot = process.cwd(), writeChanges = true) {
|
|
749
|
+
const manifests = this.findManifests(projectRoot);
|
|
750
|
+
const aggregatedDeps = {};
|
|
751
|
+
const aggregatedDevDeps = {};
|
|
752
|
+
for (const mPath of manifests) {
|
|
753
|
+
try {
|
|
754
|
+
const raw = fs.readFileSync(mPath, "utf8");
|
|
755
|
+
const json = JSON.parse(raw);
|
|
756
|
+
if (json.dependencies && typeof json.dependencies === "object") {
|
|
757
|
+
for (const [pkg, ver] of Object.entries(json.dependencies)) {
|
|
758
|
+
if (!aggregatedDeps[pkg]) aggregatedDeps[pkg] = [];
|
|
759
|
+
if (!aggregatedDeps[pkg].includes(String(ver))) {
|
|
760
|
+
aggregatedDeps[pkg].push(String(ver));
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
if (json.devDependencies && typeof json.devDependencies === "object") {
|
|
765
|
+
for (const [pkg, ver] of Object.entries(json.devDependencies)) {
|
|
766
|
+
if (!aggregatedDevDeps[pkg]) aggregatedDevDeps[pkg] = [];
|
|
767
|
+
if (!aggregatedDevDeps[pkg].includes(String(ver))) {
|
|
768
|
+
aggregatedDevDeps[pkg].push(String(ver));
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
} catch (err) {
|
|
773
|
+
console.warn(`[KrnlPackageReconciler] Warning: Could not parse ${mPath}:`, err);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
const conflicts = [];
|
|
777
|
+
const resolvedDeps = {};
|
|
778
|
+
const resolvedDevDeps = {};
|
|
779
|
+
for (const [pkg, versions] of Object.entries(aggregatedDeps)) {
|
|
780
|
+
if (versions.length > 1) {
|
|
781
|
+
conflicts.push({ package: pkg, versions });
|
|
782
|
+
}
|
|
783
|
+
resolvedDeps[pkg] = versions[versions.length - 1];
|
|
784
|
+
}
|
|
785
|
+
for (const [pkg, versions] of Object.entries(aggregatedDevDeps)) {
|
|
786
|
+
if (versions.length > 1 && !conflicts.some((c) => c.package === pkg)) {
|
|
787
|
+
conflicts.push({ package: pkg, versions });
|
|
788
|
+
}
|
|
789
|
+
resolvedDevDeps[pkg] = versions[versions.length - 1];
|
|
790
|
+
}
|
|
791
|
+
const pkgJsonPath = path.join(projectRoot, "package.json");
|
|
792
|
+
let updated = false;
|
|
793
|
+
if (fs.existsSync(pkgJsonPath)) {
|
|
794
|
+
const pkgContent = JSON.parse(fs.readFileSync(pkgJsonPath, "utf8"));
|
|
795
|
+
pkgContent.dependencies = pkgContent.dependencies || {};
|
|
796
|
+
pkgContent.devDependencies = pkgContent.devDependencies || {};
|
|
797
|
+
let hasChanges = false;
|
|
798
|
+
for (const [pkg, ver] of Object.entries(resolvedDeps)) {
|
|
799
|
+
if (pkgContent.dependencies[pkg] !== ver) {
|
|
800
|
+
pkgContent.dependencies[pkg] = ver;
|
|
801
|
+
hasChanges = true;
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
for (const [pkg, ver] of Object.entries(resolvedDevDeps)) {
|
|
805
|
+
if (!pkgContent.dependencies[pkg] && pkgContent.devDependencies[pkg] !== ver) {
|
|
806
|
+
pkgContent.devDependencies[pkg] = ver;
|
|
807
|
+
hasChanges = true;
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
if (hasChanges && writeChanges) {
|
|
811
|
+
fs.writeFileSync(pkgJsonPath, JSON.stringify(pkgContent, null, 2) + "\n");
|
|
812
|
+
updated = true;
|
|
813
|
+
console.log(`[KrnlPackageReconciler] Reconciled package.json from ${manifests.length} manifest(s).`);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
return {
|
|
817
|
+
updated,
|
|
818
|
+
totalManifests: manifests.length,
|
|
819
|
+
addedDependencies: resolvedDeps,
|
|
820
|
+
addedDevDependencies: resolvedDevDeps,
|
|
821
|
+
conflicts
|
|
822
|
+
};
|
|
823
|
+
}
|
|
824
|
+
/**
|
|
825
|
+
* Discovers all manifest.json files in krnl/ (or src/)
|
|
826
|
+
*/
|
|
827
|
+
static findManifests(projectRoot) {
|
|
828
|
+
const searchDirs = [
|
|
829
|
+
path.join(projectRoot, "krnl", "backend", "libraries"),
|
|
830
|
+
path.join(projectRoot, "krnl", "backend", "functionalities"),
|
|
831
|
+
path.join(projectRoot, "krnl", "frontend", "libraries"),
|
|
832
|
+
path.join(projectRoot, "krnl", "frontend", "functionalities"),
|
|
833
|
+
path.join(projectRoot, "src", "functionalities"),
|
|
834
|
+
path.join(projectRoot, "src", "libraries")
|
|
835
|
+
];
|
|
836
|
+
const found = [];
|
|
837
|
+
for (const dir of searchDirs) {
|
|
838
|
+
if (fs.existsSync(dir)) {
|
|
839
|
+
this.scanRecursive(dir, found);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
return found;
|
|
843
|
+
}
|
|
844
|
+
static scanRecursive(dir, found) {
|
|
845
|
+
try {
|
|
846
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
847
|
+
for (const entry of entries) {
|
|
848
|
+
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === ".git") continue;
|
|
849
|
+
const full = path.join(dir, entry.name);
|
|
850
|
+
if (entry.isDirectory()) {
|
|
851
|
+
this.scanRecursive(full, found);
|
|
852
|
+
} else if (entry.isFile() && entry.name === "manifest.json") {
|
|
853
|
+
found.push(full);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
} catch {
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
};
|
|
860
|
+
|
|
727
861
|
// src/connectivity/ProtocolResolver.ts
|
|
728
862
|
var ProtocolResolver = class {
|
|
729
863
|
static selectProtocol(requiredCapabilities, availableEndpoints) {
|
|
@@ -738,6 +872,7 @@ var ProtocolResolver = class {
|
|
|
738
872
|
// Annotate the CommonJS export names for ESM import in node:
|
|
739
873
|
0 && (module.exports = {
|
|
740
874
|
HttpProtocolAdapter,
|
|
875
|
+
KrnlPackageReconciler,
|
|
741
876
|
LifecycleManager,
|
|
742
877
|
MemoryTransport,
|
|
743
878
|
P2PProtocolAdapter,
|
|
@@ -203,7 +203,7 @@ declare class HttpProtocolAdapter implements ProtocolAdapter {
|
|
|
203
203
|
|
|
204
204
|
/**
|
|
205
205
|
* @file WebSocketProtocolAdapter.ts
|
|
206
|
-
* @description WebSocket full-duplex protocol adapter for services.
|
|
206
|
+
* @description WebSocket full-duplex protocol adapter for services (browser + Node safe).
|
|
207
207
|
*/
|
|
208
208
|
|
|
209
209
|
declare class WebSocketProtocolAdapter implements ProtocolAdapter {
|
|
@@ -310,6 +310,28 @@ declare class ServiceDiscovery {
|
|
|
310
310
|
findPeer(id: string): PeerRecord | undefined;
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
+
interface ReconcileResult {
|
|
314
|
+
updated: boolean;
|
|
315
|
+
totalManifests: number;
|
|
316
|
+
addedDependencies: Record<string, string>;
|
|
317
|
+
addedDevDependencies: Record<string, string>;
|
|
318
|
+
conflicts: Array<{
|
|
319
|
+
package: string;
|
|
320
|
+
versions: string[];
|
|
321
|
+
}>;
|
|
322
|
+
}
|
|
323
|
+
declare class KrnlPackageReconciler {
|
|
324
|
+
/**
|
|
325
|
+
* Scans all manifest.json files across backend and frontend and reconciles root package.json.
|
|
326
|
+
*/
|
|
327
|
+
static reconcile(projectRoot?: string, writeChanges?: boolean): ReconcileResult;
|
|
328
|
+
/**
|
|
329
|
+
* Discovers all manifest.json files in krnl/ (or src/)
|
|
330
|
+
*/
|
|
331
|
+
static findManifests(projectRoot: string): string[];
|
|
332
|
+
private static scanRecursive;
|
|
333
|
+
}
|
|
334
|
+
|
|
313
335
|
/**
|
|
314
336
|
* @file ServiceStateStore.ts
|
|
315
337
|
* @description State management primitive for stateful services.
|
|
@@ -357,4 +379,4 @@ declare class ProtocolResolver {
|
|
|
357
379
|
static getSupportedProtocols(definition: ServiceDefinition): ProtocolType[];
|
|
358
380
|
}
|
|
359
381
|
|
|
360
|
-
export { type Connection, type DependencyContract, type EndpointDescriptor, type EventContract, HttpProtocolAdapter, type IService, type LifecycleContract, LifecycleManager, MemoryTransport, type OperationContext, type OperationContract, P2PProtocolAdapter, type PeerRecord, type ProtocolAdapter, type ProtocolCapabilities, type ProtocolEnvelope, ProtocolResolver, type ProtocolType, type RegisteredServiceRecord, type ServiceCapability, type ServiceDefinition, ServiceDiscovery, ServiceEventBus, ServiceInstance, ServiceProxy, ServiceRegistry, ServiceRuntime, ServiceStateStore, type ServiceStatus, type StateContract, UdpProtocolAdapter, WebSocketProtocolAdapter, createService, createServiceDefinition, createServiceProxy };
|
|
382
|
+
export { type Connection, type DependencyContract, type EndpointDescriptor, type EventContract, HttpProtocolAdapter, type IService, KrnlPackageReconciler, type LifecycleContract, LifecycleManager, MemoryTransport, type OperationContext, type OperationContract, P2PProtocolAdapter, type PeerRecord, type ProtocolAdapter, type ProtocolCapabilities, type ProtocolEnvelope, ProtocolResolver, type ProtocolType, type ReconcileResult, type RegisteredServiceRecord, type ServiceCapability, type ServiceDefinition, ServiceDiscovery, ServiceEventBus, ServiceInstance, ServiceProxy, ServiceRegistry, ServiceRuntime, ServiceStateStore, type ServiceStatus, type StateContract, UdpProtocolAdapter, WebSocketProtocolAdapter, createService, createServiceDefinition, createServiceProxy };
|
|
@@ -203,7 +203,7 @@ declare class HttpProtocolAdapter implements ProtocolAdapter {
|
|
|
203
203
|
|
|
204
204
|
/**
|
|
205
205
|
* @file WebSocketProtocolAdapter.ts
|
|
206
|
-
* @description WebSocket full-duplex protocol adapter for services.
|
|
206
|
+
* @description WebSocket full-duplex protocol adapter for services (browser + Node safe).
|
|
207
207
|
*/
|
|
208
208
|
|
|
209
209
|
declare class WebSocketProtocolAdapter implements ProtocolAdapter {
|
|
@@ -310,6 +310,28 @@ declare class ServiceDiscovery {
|
|
|
310
310
|
findPeer(id: string): PeerRecord | undefined;
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
+
interface ReconcileResult {
|
|
314
|
+
updated: boolean;
|
|
315
|
+
totalManifests: number;
|
|
316
|
+
addedDependencies: Record<string, string>;
|
|
317
|
+
addedDevDependencies: Record<string, string>;
|
|
318
|
+
conflicts: Array<{
|
|
319
|
+
package: string;
|
|
320
|
+
versions: string[];
|
|
321
|
+
}>;
|
|
322
|
+
}
|
|
323
|
+
declare class KrnlPackageReconciler {
|
|
324
|
+
/**
|
|
325
|
+
* Scans all manifest.json files across backend and frontend and reconciles root package.json.
|
|
326
|
+
*/
|
|
327
|
+
static reconcile(projectRoot?: string, writeChanges?: boolean): ReconcileResult;
|
|
328
|
+
/**
|
|
329
|
+
* Discovers all manifest.json files in krnl/ (or src/)
|
|
330
|
+
*/
|
|
331
|
+
static findManifests(projectRoot: string): string[];
|
|
332
|
+
private static scanRecursive;
|
|
333
|
+
}
|
|
334
|
+
|
|
313
335
|
/**
|
|
314
336
|
* @file ServiceStateStore.ts
|
|
315
337
|
* @description State management primitive for stateful services.
|
|
@@ -357,4 +379,4 @@ declare class ProtocolResolver {
|
|
|
357
379
|
static getSupportedProtocols(definition: ServiceDefinition): ProtocolType[];
|
|
358
380
|
}
|
|
359
381
|
|
|
360
|
-
export { type Connection, type DependencyContract, type EndpointDescriptor, type EventContract, HttpProtocolAdapter, type IService, type LifecycleContract, LifecycleManager, MemoryTransport, type OperationContext, type OperationContract, P2PProtocolAdapter, type PeerRecord, type ProtocolAdapter, type ProtocolCapabilities, type ProtocolEnvelope, ProtocolResolver, type ProtocolType, type RegisteredServiceRecord, type ServiceCapability, type ServiceDefinition, ServiceDiscovery, ServiceEventBus, ServiceInstance, ServiceProxy, ServiceRegistry, ServiceRuntime, ServiceStateStore, type ServiceStatus, type StateContract, UdpProtocolAdapter, WebSocketProtocolAdapter, createService, createServiceDefinition, createServiceProxy };
|
|
382
|
+
export { type Connection, type DependencyContract, type EndpointDescriptor, type EventContract, HttpProtocolAdapter, type IService, KrnlPackageReconciler, type LifecycleContract, LifecycleManager, MemoryTransport, type OperationContext, type OperationContract, P2PProtocolAdapter, type PeerRecord, type ProtocolAdapter, type ProtocolCapabilities, type ProtocolEnvelope, ProtocolResolver, type ProtocolType, type ReconcileResult, type RegisteredServiceRecord, type ServiceCapability, type ServiceDefinition, ServiceDiscovery, ServiceEventBus, ServiceInstance, ServiceProxy, ServiceRegistry, ServiceRuntime, ServiceStateStore, type ServiceStatus, type StateContract, UdpProtocolAdapter, WebSocketProtocolAdapter, createService, createServiceDefinition, createServiceProxy };
|
|
@@ -330,8 +330,6 @@ var HttpProtocolAdapter = class {
|
|
|
330
330
|
};
|
|
331
331
|
|
|
332
332
|
// src/protocols/WebSocketProtocolAdapter.ts
|
|
333
|
-
import http2 from "http";
|
|
334
|
-
import { WebSocketServer, WebSocket } from "ws";
|
|
335
333
|
var WebSocketProtocolAdapter = class {
|
|
336
334
|
protocol = "ws";
|
|
337
335
|
capabilities = {
|
|
@@ -347,6 +345,13 @@ var WebSocketProtocolAdapter = class {
|
|
|
347
345
|
wss;
|
|
348
346
|
port;
|
|
349
347
|
async expose(service, port = 0) {
|
|
348
|
+
const httpMod = await import("http");
|
|
349
|
+
const http2 = httpMod.default || httpMod;
|
|
350
|
+
const wsMod = await import("ws").catch(() => null);
|
|
351
|
+
if (!wsMod) {
|
|
352
|
+
throw new Error('WebSocketProtocolAdapter.expose requires "ws" package in Node.js environment.');
|
|
353
|
+
}
|
|
354
|
+
const WebSocketServer = wsMod.WebSocketServer || wsMod.default?.WebSocketServer || wsMod.Server;
|
|
350
355
|
this.server = http2.createServer();
|
|
351
356
|
this.wss = new WebSocketServer({ server: this.server });
|
|
352
357
|
this.wss.on("connection", (ws) => {
|
|
@@ -393,8 +398,16 @@ var WebSocketProtocolAdapter = class {
|
|
|
393
398
|
};
|
|
394
399
|
}
|
|
395
400
|
async send(endpoint, envelope) {
|
|
401
|
+
let WS = globalThis.WebSocket;
|
|
402
|
+
if (!WS) {
|
|
403
|
+
const wsMod = await import("ws").catch(() => null);
|
|
404
|
+
WS = wsMod?.WebSocket || wsMod?.default?.WebSocket || wsMod;
|
|
405
|
+
}
|
|
406
|
+
if (!WS) {
|
|
407
|
+
throw new Error("No WebSocket client implementation available in this environment.");
|
|
408
|
+
}
|
|
396
409
|
return new Promise((resolve, reject) => {
|
|
397
|
-
const ws = new
|
|
410
|
+
const ws = new WS(`ws://${endpoint.address}:${endpoint.port}`);
|
|
398
411
|
ws.on("open", () => {
|
|
399
412
|
ws.send(JSON.stringify(envelope));
|
|
400
413
|
});
|
|
@@ -672,6 +685,126 @@ var ServiceDiscovery = class {
|
|
|
672
685
|
}
|
|
673
686
|
};
|
|
674
687
|
|
|
688
|
+
// src/discovery/KrnlPackageReconciler.ts
|
|
689
|
+
import * as fs from "fs";
|
|
690
|
+
import * as path from "path";
|
|
691
|
+
var KrnlPackageReconciler = class {
|
|
692
|
+
/**
|
|
693
|
+
* Scans all manifest.json files across backend and frontend and reconciles root package.json.
|
|
694
|
+
*/
|
|
695
|
+
static reconcile(projectRoot = process.cwd(), writeChanges = true) {
|
|
696
|
+
const manifests = this.findManifests(projectRoot);
|
|
697
|
+
const aggregatedDeps = {};
|
|
698
|
+
const aggregatedDevDeps = {};
|
|
699
|
+
for (const mPath of manifests) {
|
|
700
|
+
try {
|
|
701
|
+
const raw = fs.readFileSync(mPath, "utf8");
|
|
702
|
+
const json = JSON.parse(raw);
|
|
703
|
+
if (json.dependencies && typeof json.dependencies === "object") {
|
|
704
|
+
for (const [pkg, ver] of Object.entries(json.dependencies)) {
|
|
705
|
+
if (!aggregatedDeps[pkg]) aggregatedDeps[pkg] = [];
|
|
706
|
+
if (!aggregatedDeps[pkg].includes(String(ver))) {
|
|
707
|
+
aggregatedDeps[pkg].push(String(ver));
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
if (json.devDependencies && typeof json.devDependencies === "object") {
|
|
712
|
+
for (const [pkg, ver] of Object.entries(json.devDependencies)) {
|
|
713
|
+
if (!aggregatedDevDeps[pkg]) aggregatedDevDeps[pkg] = [];
|
|
714
|
+
if (!aggregatedDevDeps[pkg].includes(String(ver))) {
|
|
715
|
+
aggregatedDevDeps[pkg].push(String(ver));
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
} catch (err) {
|
|
720
|
+
console.warn(`[KrnlPackageReconciler] Warning: Could not parse ${mPath}:`, err);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
const conflicts = [];
|
|
724
|
+
const resolvedDeps = {};
|
|
725
|
+
const resolvedDevDeps = {};
|
|
726
|
+
for (const [pkg, versions] of Object.entries(aggregatedDeps)) {
|
|
727
|
+
if (versions.length > 1) {
|
|
728
|
+
conflicts.push({ package: pkg, versions });
|
|
729
|
+
}
|
|
730
|
+
resolvedDeps[pkg] = versions[versions.length - 1];
|
|
731
|
+
}
|
|
732
|
+
for (const [pkg, versions] of Object.entries(aggregatedDevDeps)) {
|
|
733
|
+
if (versions.length > 1 && !conflicts.some((c) => c.package === pkg)) {
|
|
734
|
+
conflicts.push({ package: pkg, versions });
|
|
735
|
+
}
|
|
736
|
+
resolvedDevDeps[pkg] = versions[versions.length - 1];
|
|
737
|
+
}
|
|
738
|
+
const pkgJsonPath = path.join(projectRoot, "package.json");
|
|
739
|
+
let updated = false;
|
|
740
|
+
if (fs.existsSync(pkgJsonPath)) {
|
|
741
|
+
const pkgContent = JSON.parse(fs.readFileSync(pkgJsonPath, "utf8"));
|
|
742
|
+
pkgContent.dependencies = pkgContent.dependencies || {};
|
|
743
|
+
pkgContent.devDependencies = pkgContent.devDependencies || {};
|
|
744
|
+
let hasChanges = false;
|
|
745
|
+
for (const [pkg, ver] of Object.entries(resolvedDeps)) {
|
|
746
|
+
if (pkgContent.dependencies[pkg] !== ver) {
|
|
747
|
+
pkgContent.dependencies[pkg] = ver;
|
|
748
|
+
hasChanges = true;
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
for (const [pkg, ver] of Object.entries(resolvedDevDeps)) {
|
|
752
|
+
if (!pkgContent.dependencies[pkg] && pkgContent.devDependencies[pkg] !== ver) {
|
|
753
|
+
pkgContent.devDependencies[pkg] = ver;
|
|
754
|
+
hasChanges = true;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
if (hasChanges && writeChanges) {
|
|
758
|
+
fs.writeFileSync(pkgJsonPath, JSON.stringify(pkgContent, null, 2) + "\n");
|
|
759
|
+
updated = true;
|
|
760
|
+
console.log(`[KrnlPackageReconciler] Reconciled package.json from ${manifests.length} manifest(s).`);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
return {
|
|
764
|
+
updated,
|
|
765
|
+
totalManifests: manifests.length,
|
|
766
|
+
addedDependencies: resolvedDeps,
|
|
767
|
+
addedDevDependencies: resolvedDevDeps,
|
|
768
|
+
conflicts
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
/**
|
|
772
|
+
* Discovers all manifest.json files in krnl/ (or src/)
|
|
773
|
+
*/
|
|
774
|
+
static findManifests(projectRoot) {
|
|
775
|
+
const searchDirs = [
|
|
776
|
+
path.join(projectRoot, "krnl", "backend", "libraries"),
|
|
777
|
+
path.join(projectRoot, "krnl", "backend", "functionalities"),
|
|
778
|
+
path.join(projectRoot, "krnl", "frontend", "libraries"),
|
|
779
|
+
path.join(projectRoot, "krnl", "frontend", "functionalities"),
|
|
780
|
+
path.join(projectRoot, "src", "functionalities"),
|
|
781
|
+
path.join(projectRoot, "src", "libraries")
|
|
782
|
+
];
|
|
783
|
+
const found = [];
|
|
784
|
+
for (const dir of searchDirs) {
|
|
785
|
+
if (fs.existsSync(dir)) {
|
|
786
|
+
this.scanRecursive(dir, found);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
return found;
|
|
790
|
+
}
|
|
791
|
+
static scanRecursive(dir, found) {
|
|
792
|
+
try {
|
|
793
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
794
|
+
for (const entry of entries) {
|
|
795
|
+
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === ".git") continue;
|
|
796
|
+
const full = path.join(dir, entry.name);
|
|
797
|
+
if (entry.isDirectory()) {
|
|
798
|
+
this.scanRecursive(full, found);
|
|
799
|
+
} else if (entry.isFile() && entry.name === "manifest.json") {
|
|
800
|
+
found.push(full);
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
} catch {
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
};
|
|
807
|
+
|
|
675
808
|
// src/connectivity/ProtocolResolver.ts
|
|
676
809
|
var ProtocolResolver = class {
|
|
677
810
|
static selectProtocol(requiredCapabilities, availableEndpoints) {
|
|
@@ -685,6 +818,7 @@ var ProtocolResolver = class {
|
|
|
685
818
|
};
|
|
686
819
|
export {
|
|
687
820
|
HttpProtocolAdapter,
|
|
821
|
+
KrnlPackageReconciler,
|
|
688
822
|
LifecycleManager,
|
|
689
823
|
MemoryTransport,
|
|
690
824
|
P2PProtocolAdapter,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dinilmusick/krnl-core",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Core runtime engine,
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Core runtime engine, Service facades, Protocols, Transports, and Execution flows for Krnl backend services",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|