@telorun/kernel 0.6.0 → 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.
- package/dist/controller-loader.d.ts +57 -0
- package/dist/controller-loader.d.ts.map +1 -1
- package/dist/controller-loader.js +33 -3
- package/dist/controller-loader.js.map +1 -1
- package/dist/controller-loaders/napi-loader.d.ts +33 -1
- package/dist/controller-loaders/napi-loader.d.ts.map +1 -1
- package/dist/controller-loaders/napi-loader.js +101 -8
- package/dist/controller-loaders/napi-loader.js.map +1 -1
- package/dist/controller-loaders/npm-loader.d.ts +12 -1
- package/dist/controller-loaders/npm-loader.d.ts.map +1 -1
- package/dist/controller-loaders/npm-loader.js +9 -4
- package/dist/controller-loaders/npm-loader.js.map +1 -1
- package/dist/controllers/resource-definition/resource-definition-controller.d.ts +1 -3
- package/dist/controllers/resource-definition/resource-definition-controller.d.ts.map +1 -1
- package/dist/controllers/resource-definition/resource-definition-controller.js +13 -14
- package/dist/controllers/resource-definition/resource-definition-controller.js.map +1 -1
- package/dist/evaluation-context.d.ts +17 -2
- package/dist/evaluation-context.d.ts.map +1 -1
- package/dist/evaluation-context.js +105 -28
- package/dist/evaluation-context.js.map +1 -1
- package/dist/kernel.js +22 -0
- package/dist/kernel.js.map +1 -1
- package/package.json +3 -3
- package/src/controller-loader.ts +82 -6
- package/src/controller-loaders/napi-loader.ts +143 -10
- package/src/controller-loaders/npm-loader.ts +27 -6
- package/src/controllers/resource-definition/resource-definition-controller.ts +21 -23
- package/src/evaluation-context.ts +107 -30
- package/src/kernel.ts +21 -0
|
@@ -1,6 +1,57 @@
|
|
|
1
1
|
import { ControllerInstance } from "@telorun/sdk";
|
|
2
2
|
import { ControllerPolicy } from "./runtime-registry.js";
|
|
3
3
|
export type { ControllerPolicy } from "./runtime-registry.js";
|
|
4
|
+
/**
|
|
5
|
+
* Which branch the per-scheme loader actually took. Cache/local hits resolve
|
|
6
|
+
* in milliseconds; `npm-install` and `cargo-build` are the only branches that
|
|
7
|
+
* do real (network or compile) work. The CLI uses this to decide whether a
|
|
8
|
+
* "downloading…" line was honest or should be erased.
|
|
9
|
+
*/
|
|
10
|
+
export type ControllerResolveSource = "local" | "node_modules" | "cache" | "npm-install" | "cargo-build";
|
|
11
|
+
export type ControllerLoaderEvent = {
|
|
12
|
+
name: "ControllerLoading";
|
|
13
|
+
payload: {
|
|
14
|
+
purl: string;
|
|
15
|
+
};
|
|
16
|
+
} | {
|
|
17
|
+
name: "ControllerLoaded";
|
|
18
|
+
payload: {
|
|
19
|
+
purl: string;
|
|
20
|
+
source: ControllerResolveSource;
|
|
21
|
+
durationMs: number;
|
|
22
|
+
};
|
|
23
|
+
} | {
|
|
24
|
+
name: "ControllerLoadFailed";
|
|
25
|
+
payload: {
|
|
26
|
+
purl: string;
|
|
27
|
+
error: string;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The candidate at `purl` couldn't be tried in this environment (e.g.
|
|
32
|
+
* `pkg:cargo` with no `rustc` on PATH, or an unsupported scheme) and the
|
|
33
|
+
* dispatcher has moved on to the next candidate. Distinct from `Failed`,
|
|
34
|
+
* which is non-recoverable. Consumers that opened a UI element on the
|
|
35
|
+
* matching `ControllerLoading` should close it out here.
|
|
36
|
+
*/
|
|
37
|
+
| {
|
|
38
|
+
name: "ControllerLoadSkipped";
|
|
39
|
+
payload: {
|
|
40
|
+
purl: string;
|
|
41
|
+
reason: string;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* The dispatcher awaits each emission, so the callback may be async without
|
|
46
|
+
* risking out-of-order delivery (concurrent definition loads emit in
|
|
47
|
+
* parallel; the await pins each pair of `Loading`/`Loaded` events to the
|
|
48
|
+
* same async chain). The kernel's `ctx.emit` is async, hence `Promise<void>`
|
|
49
|
+
* is allowed.
|
|
50
|
+
*/
|
|
51
|
+
export type ControllerLoaderEmit = (event: ControllerLoaderEvent) => void | Promise<void>;
|
|
52
|
+
export interface ControllerLoaderOptions {
|
|
53
|
+
emit?: ControllerLoaderEmit;
|
|
54
|
+
}
|
|
4
55
|
/**
|
|
5
56
|
* Top-level controller-loader dispatcher. Picks a per-scheme sub-loader by
|
|
6
57
|
* PURL type and applies the resolved selection policy:
|
|
@@ -13,10 +64,16 @@ export type { ControllerPolicy } from "./runtime-registry.js";
|
|
|
13
64
|
* Recovery: env-missing failures (`ControllerEnvMissingError`) advance to the
|
|
14
65
|
* next candidate. User-code failures (`RuntimeError("ERR_CONTROLLER_BUILD_FAILED" | "ERR_CONTROLLER_INVALID")`)
|
|
15
66
|
* fail hard regardless of remaining candidates.
|
|
67
|
+
*
|
|
68
|
+
* Lifecycle events are emitted per *attempt*, so a fallback chain produces one
|
|
69
|
+
* `ControllerLoading` per candidate tried plus a final `ControllerLoaded` (or
|
|
70
|
+
* `ControllerLoadFailed`) for the one that won.
|
|
16
71
|
*/
|
|
17
72
|
export declare class ControllerLoader {
|
|
18
73
|
private npmLoader;
|
|
19
74
|
private napiLoader;
|
|
75
|
+
private emit?;
|
|
76
|
+
constructor(options?: ControllerLoaderOptions);
|
|
20
77
|
load(purlCandidates: string[], baseUri: string, policy?: ControllerPolicy): Promise<ControllerInstance>;
|
|
21
78
|
private dispatchOne;
|
|
22
79
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller-loader.d.ts","sourceRoot":"","sources":["../src/controller-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAgB,MAAM,cAAc,CAAC;AAGhE,OAAO,EAAE,gBAAgB,EAAmC,MAAM,uBAAuB,CAAC;AAE1F,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D
|
|
1
|
+
{"version":3,"file":"controller-loader.d.ts","sourceRoot":"","sources":["../src/controller-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAgB,MAAM,cAAc,CAAC;AAGhE,OAAO,EAAE,gBAAgB,EAAmC,MAAM,uBAAuB,CAAC;AAE1F,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAC/B,OAAO,GACP,cAAc,GACd,OAAO,GACP,aAAa,GACb,aAAa,CAAC;AAElB,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACxD;IACE,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,uBAAuB,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CAChF,GACD;IAAE,IAAI,EAAE,sBAAsB,CAAC;IAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE;AAC5E;;;;;;GAMG;GACD;IAAE,IAAI,EAAE,uBAAuB,CAAC;IAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAEjF;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1F,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,oBAAoB,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,IAAI,CAAC,CAAuB;gBAExB,OAAO,GAAE,uBAA4B;IAI3C,IAAI,CACR,cAAc,EAAE,MAAM,EAAE,EACxB,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,gBAAgB,GACxB,OAAO,CAAC,kBAAkB,CAAC;YAqDhB,WAAW;CAY1B"}
|
|
@@ -14,11 +14,16 @@ import { DEFAULT_POLICY, POLICY_WILDCARD } from "./runtime-registry.js";
|
|
|
14
14
|
* Recovery: env-missing failures (`ControllerEnvMissingError`) advance to the
|
|
15
15
|
* next candidate. User-code failures (`RuntimeError("ERR_CONTROLLER_BUILD_FAILED" | "ERR_CONTROLLER_INVALID")`)
|
|
16
16
|
* fail hard regardless of remaining candidates.
|
|
17
|
+
*
|
|
18
|
+
* Lifecycle events are emitted per *attempt*, so a fallback chain produces one
|
|
19
|
+
* `ControllerLoading` per candidate tried plus a final `ControllerLoaded` (or
|
|
20
|
+
* `ControllerLoadFailed`) for the one that won.
|
|
17
21
|
*/
|
|
18
22
|
export class ControllerLoader {
|
|
19
|
-
constructor() {
|
|
23
|
+
constructor(options = {}) {
|
|
20
24
|
this.npmLoader = new NpmControllerLoader();
|
|
21
25
|
this.napiLoader = new NapiControllerLoader();
|
|
26
|
+
this.emit = options.emit;
|
|
22
27
|
}
|
|
23
28
|
async load(purlCandidates, baseUri, policy) {
|
|
24
29
|
if (!purlCandidates || purlCandidates.length === 0) {
|
|
@@ -31,18 +36,43 @@ export class ControllerLoader {
|
|
|
31
36
|
}
|
|
32
37
|
const errors = [];
|
|
33
38
|
for (const purl of ordered) {
|
|
39
|
+
await this.emit?.({ name: "ControllerLoading", payload: { purl } });
|
|
40
|
+
const startedAt = Date.now();
|
|
34
41
|
try {
|
|
35
|
-
|
|
42
|
+
const { instance, source } = await this.dispatchOne(purl, baseUri);
|
|
43
|
+
await this.emit?.({
|
|
44
|
+
name: "ControllerLoaded",
|
|
45
|
+
payload: { purl, source, durationMs: Date.now() - startedAt },
|
|
46
|
+
});
|
|
47
|
+
return instance;
|
|
36
48
|
}
|
|
37
49
|
catch (err) {
|
|
38
50
|
if (err instanceof ControllerEnvMissingError) {
|
|
39
51
|
errors.push(`${purl}: ${err.message}`);
|
|
52
|
+
// Env-missing isn't a hard failure — the dispatcher will try the
|
|
53
|
+
// next candidate. We still emit a terminal event for *this* attempt
|
|
54
|
+
// so consumers (notably the CLI progress renderer) can close out
|
|
55
|
+
// the UI state opened by the matching ControllerLoading. Without
|
|
56
|
+
// this, every fallback attempt would leak a pending `⬇` line.
|
|
57
|
+
await this.emit?.({
|
|
58
|
+
name: "ControllerLoadSkipped",
|
|
59
|
+
payload: { purl, reason: err.message },
|
|
60
|
+
});
|
|
40
61
|
continue;
|
|
41
62
|
}
|
|
63
|
+
await this.emit?.({
|
|
64
|
+
name: "ControllerLoadFailed",
|
|
65
|
+
payload: { purl, error: err instanceof Error ? err.message : String(err) },
|
|
66
|
+
});
|
|
42
67
|
throw err;
|
|
43
68
|
}
|
|
44
69
|
}
|
|
45
|
-
|
|
70
|
+
const aggregated = `No controller resolved. Tried ${ordered.length} candidate(s):\n${errors.join("\n")}`;
|
|
71
|
+
await this.emit?.({
|
|
72
|
+
name: "ControllerLoadFailed",
|
|
73
|
+
payload: { purl: ordered[ordered.length - 1], error: aggregated },
|
|
74
|
+
});
|
|
75
|
+
throw new RuntimeError("ERR_CONTROLLER_NOT_FOUND", aggregated);
|
|
46
76
|
}
|
|
47
77
|
async dispatchOne(purl, baseUri) {
|
|
48
78
|
if (purl.startsWith("pkg:npm")) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller-loader.js","sourceRoot":"","sources":["../src/controller-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,YAAY,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AACtG,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAoB,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"controller-loader.js","sourceRoot":"","sources":["../src/controller-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,27 @@ export declare class ControllerEnvMissingError extends Error {
|
|
|
10
10
|
readonly _envMissing: true;
|
|
11
11
|
constructor(message: string);
|
|
12
12
|
}
|
|
13
|
+
export declare function __getNapiBuildAttempts(): number;
|
|
14
|
+
export declare function __resetNapiLoaderForTest(): void;
|
|
15
|
+
/**
|
|
16
|
+
* Which branch of the resolver served this load.
|
|
17
|
+
*
|
|
18
|
+
* - `cache` — process-lifetime in-memory hit on `_napiModuleCache`.
|
|
19
|
+
* - `local` — `local_path` qualifier; cargo was invoked but the work
|
|
20
|
+
* is conceptually equivalent to "found source on disk and
|
|
21
|
+
* used it" (parallel to the npm `local_path` branch). The
|
|
22
|
+
* CLI silences these by default; the first cold build on
|
|
23
|
+
* a fresh checkout is silent for the same reason.
|
|
24
|
+
* - `cargo-build`— reserved for distribution-mode resolution (fetch from a
|
|
25
|
+
* registry + compile). Not produced today; the dispatcher
|
|
26
|
+
* errors with `ControllerEnvMissingError` for non-local
|
|
27
|
+
* PURLs (see [napi-loader.ts:62-66] in this file).
|
|
28
|
+
*/
|
|
29
|
+
export type NapiResolveSource = "cache" | "local" | "cargo-build";
|
|
30
|
+
export interface NapiLoadResult {
|
|
31
|
+
instance: ControllerInstance;
|
|
32
|
+
source: NapiResolveSource;
|
|
33
|
+
}
|
|
13
34
|
export declare class NapiControllerLoader {
|
|
14
35
|
/**
|
|
15
36
|
* Resolve a `pkg:cargo/...` PURL to a controller module instance by building
|
|
@@ -21,7 +42,18 @@ export declare class NapiControllerLoader {
|
|
|
21
42
|
*
|
|
22
43
|
* Distribution mode (no local_path): out of scope for the PoC; the hook is
|
|
23
44
|
* left in place so the dispatcher reports env-missing and falls through.
|
|
45
|
+
*
|
|
46
|
+
* Fragment (`#entry`) is optional. When absent, the whole `require()`'d
|
|
47
|
+
* module is returned as the controller — the legacy single-export
|
|
48
|
+
* convention. When present, the fragment is treated as a property name on
|
|
49
|
+
* the loaded module: e.g. `pkg:cargo/foo?local_path=...#bar` returns
|
|
50
|
+
* `module.bar` as the controller. This mirrors the npm `#entry` semantics
|
|
51
|
+
* but indexes into the flat napi export bag instead of opening a different
|
|
52
|
+
* file. The convention is "one source file per controller, top-level
|
|
53
|
+
* export name matches the file" — files-as-controllers in spirit, even
|
|
54
|
+
* though all exports come from one linked dylib.
|
|
24
55
|
*/
|
|
25
|
-
load(purl: string, baseUri: string): Promise<
|
|
56
|
+
load(purl: string, baseUri: string): Promise<NapiLoadResult>;
|
|
57
|
+
private buildAndLoad;
|
|
26
58
|
}
|
|
27
59
|
//# sourceMappingURL=napi-loader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"napi-loader.d.ts","sourceRoot":"","sources":["../../src/controller-loaders/napi-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAgB,MAAM,cAAc,CAAC;AAWhE;;;;;;GAMG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,QAAQ,CAAC,WAAW,EAAG,IAAI,CAAU;gBACzB,OAAO,EAAE,MAAM;CAI5B;
|
|
1
|
+
{"version":3,"file":"napi-loader.d.ts","sourceRoot":"","sources":["../../src/controller-loaders/napi-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAgB,MAAM,cAAc,CAAC;AAWhE;;;;;;GAMG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,QAAQ,CAAC,WAAW,EAAG,IAAI,CAAU;gBACzB,OAAO,EAAE,MAAM;CAI5B;AAgDD,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AACD,wBAAgB,wBAAwB,IAAI,IAAI,CAI/C;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,OAAO,GAAG,aAAa,CAAC;AAElE,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAED,qBAAa,oBAAoB;IAC/B;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;YA6DpD,YAAY;CAwD3B"}
|
|
@@ -36,7 +36,38 @@ export class ControllerEnvMissingError extends Error {
|
|
|
36
36
|
* crate path (not on the caller's baseUri) ensures two distinct paths that
|
|
37
37
|
* point at the same crate share one cache entry.
|
|
38
38
|
*/
|
|
39
|
+
/**
|
|
40
|
+
* Holds the *raw* `require()`'d module object — i.e. the flat export bag
|
|
41
|
+
* returned by the napi addon — keyed by canonical crate path. The PURL
|
|
42
|
+
* fragment (`#entry`) projects out a sub-export at call time; caching the
|
|
43
|
+
* raw module here means two PURLs that differ only by fragment share one
|
|
44
|
+
* cargo build / one mmap of the dylib, instead of paying for either twice.
|
|
45
|
+
*/
|
|
39
46
|
const _napiModuleCache = new Map();
|
|
47
|
+
/**
|
|
48
|
+
* Single-flight dedupe for concurrent loads of the same crate. Without this,
|
|
49
|
+
* two callers (e.g. parallel test kernels) both miss the module cache, both
|
|
50
|
+
* run cargo + `fs.copyFile` over the same `.node` file, and the second
|
|
51
|
+
* `copyFile` overwrites a dylib Node has already mmapped — leading to a
|
|
52
|
+
* segfault when napi finalize callbacks run against torn pages. Keeping the
|
|
53
|
+
* in-flight promise here lets late arrivals await the in-progress load and
|
|
54
|
+
* read from the populated module cache when it resolves.
|
|
55
|
+
*/
|
|
56
|
+
const _napiInFlight = new Map();
|
|
57
|
+
/**
|
|
58
|
+
* @internal Slow-path entry counter — the regression test for concurrent
|
|
59
|
+
* loads asserts this stays at 1 across N parallel callers, proving the
|
|
60
|
+
* single-flight gate held. Production code never reads it.
|
|
61
|
+
*/
|
|
62
|
+
let _napiBuildAttempts = 0;
|
|
63
|
+
export function __getNapiBuildAttempts() {
|
|
64
|
+
return _napiBuildAttempts;
|
|
65
|
+
}
|
|
66
|
+
export function __resetNapiLoaderForTest() {
|
|
67
|
+
_napiBuildAttempts = 0;
|
|
68
|
+
_napiModuleCache.clear();
|
|
69
|
+
_napiInFlight.clear();
|
|
70
|
+
}
|
|
40
71
|
export class NapiControllerLoader {
|
|
41
72
|
/**
|
|
42
73
|
* Resolve a `pkg:cargo/...` PURL to a controller module instance by building
|
|
@@ -48,9 +79,19 @@ export class NapiControllerLoader {
|
|
|
48
79
|
*
|
|
49
80
|
* Distribution mode (no local_path): out of scope for the PoC; the hook is
|
|
50
81
|
* left in place so the dispatcher reports env-missing and falls through.
|
|
82
|
+
*
|
|
83
|
+
* Fragment (`#entry`) is optional. When absent, the whole `require()`'d
|
|
84
|
+
* module is returned as the controller — the legacy single-export
|
|
85
|
+
* convention. When present, the fragment is treated as a property name on
|
|
86
|
+
* the loaded module: e.g. `pkg:cargo/foo?local_path=...#bar` returns
|
|
87
|
+
* `module.bar` as the controller. This mirrors the npm `#entry` semantics
|
|
88
|
+
* but indexes into the flat napi export bag instead of opening a different
|
|
89
|
+
* file. The convention is "one source file per controller, top-level
|
|
90
|
+
* export name matches the file" — files-as-controllers in spirit, even
|
|
91
|
+
* though all exports come from one linked dylib.
|
|
51
92
|
*/
|
|
52
93
|
async load(purl, baseUri) {
|
|
53
|
-
const [, , name, , qualifiers] = PackageURL.parseString(purl);
|
|
94
|
+
const [, , name, , qualifiers, entry] = PackageURL.parseString(purl);
|
|
54
95
|
const localPath = qualifiers?.get("local_path");
|
|
55
96
|
const isLocalManifest = baseUri && !baseUri.startsWith("http://") && !baseUri.startsWith("https://");
|
|
56
97
|
if (!localPath || !isLocalManifest) {
|
|
@@ -71,8 +112,38 @@ export class NapiControllerLoader {
|
|
|
71
112
|
const cacheKey = canonicalCratePath;
|
|
72
113
|
const cached = _napiModuleCache.get(cacheKey);
|
|
73
114
|
if (cached) {
|
|
74
|
-
return cached;
|
|
115
|
+
return { instance: project(cached, entry, cratePath), source: "cache" };
|
|
75
116
|
}
|
|
117
|
+
// Concurrent callers for the same crate await one shared build. They
|
|
118
|
+
// report `local` (not `cache`): they paid the same wall-clock cost as
|
|
119
|
+
// the originator, just by sharing one cargo invocation rather than
|
|
120
|
+
// running their own. Reporting `cache` here would mislead metrics/event
|
|
121
|
+
// consumers into thinking it was a sub-ms hit.
|
|
122
|
+
const existingInFlight = _napiInFlight.get(cacheKey);
|
|
123
|
+
if (existingInFlight) {
|
|
124
|
+
const { rawModule } = await existingInFlight;
|
|
125
|
+
return { instance: project(rawModule, entry, cratePath), source: "local" };
|
|
126
|
+
}
|
|
127
|
+
const buildPromise = this.buildAndLoad(cratePath, name ?? "", cacheKey);
|
|
128
|
+
_napiInFlight.set(cacheKey, buildPromise);
|
|
129
|
+
let rawModule;
|
|
130
|
+
let nodePath;
|
|
131
|
+
try {
|
|
132
|
+
({ rawModule, nodePath } = await buildPromise);
|
|
133
|
+
}
|
|
134
|
+
finally {
|
|
135
|
+
_napiInFlight.delete(cacheKey);
|
|
136
|
+
}
|
|
137
|
+
// `local` rather than `cargo-build` because the only mode currently
|
|
138
|
+
// wired up is `local_path` dev-mode — cargo's incremental cache means
|
|
139
|
+
// every run after the first is ~50ms of cargo-startup with no real
|
|
140
|
+
// compilation, conceptually the same as the npm `local_path` branch
|
|
141
|
+
// that just imports source already on disk. Distribution mode (when
|
|
142
|
+
// implemented) will return `cargo-build` from its own branch.
|
|
143
|
+
return { instance: project(rawModule, entry, nodePath), source: "local" };
|
|
144
|
+
}
|
|
145
|
+
async buildAndLoad(cratePath, fallbackName, cacheKey) {
|
|
146
|
+
_napiBuildAttempts++;
|
|
76
147
|
try {
|
|
77
148
|
await execFileAsync("rustc", ["--version"]);
|
|
78
149
|
}
|
|
@@ -94,26 +165,48 @@ export class NapiControllerLoader {
|
|
|
94
165
|
const stderr = err?.stderr ? `\n${err.stderr}` : "";
|
|
95
166
|
throw new RuntimeError("ERR_CONTROLLER_BUILD_FAILED", `cargo build failed for ${cratePath}:${stderr}`);
|
|
96
167
|
}
|
|
97
|
-
const { targetDir, libName } = await resolveCrateMetadata(cratePath,
|
|
168
|
+
const { targetDir, libName } = await resolveCrateMetadata(cratePath, fallbackName);
|
|
98
169
|
const dylibPath = await findDylib(targetDir, libName);
|
|
99
170
|
if (!dylibPath) {
|
|
100
171
|
throw new RuntimeError("ERR_CONTROLLER_BUILD_FAILED", `cargo build succeeded but no cdylib found for ${libName} under ${path.join(targetDir, "release")}/`);
|
|
101
172
|
}
|
|
102
173
|
const nodePath = path.join(path.dirname(dylibPath), `${libName}.node`);
|
|
103
174
|
await fs.copyFile(dylibPath, nodePath);
|
|
104
|
-
let
|
|
175
|
+
let rawModule;
|
|
105
176
|
try {
|
|
106
|
-
|
|
177
|
+
rawModule = requireFromHere(nodePath);
|
|
107
178
|
}
|
|
108
179
|
catch (err) {
|
|
109
180
|
throw new RuntimeError("ERR_CONTROLLER_INVALID", `Failed to load native addon ${nodePath}: ${err.message}`);
|
|
110
181
|
}
|
|
111
|
-
|
|
112
|
-
|
|
182
|
+
_napiModuleCache.set(cacheKey, rawModule);
|
|
183
|
+
return { rawModule, nodePath };
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Pick the controller out of the raw napi module. With no fragment, the
|
|
188
|
+
* whole module *is* the controller (legacy single-export shape). With a
|
|
189
|
+
* fragment, look up `module[entry]` — convention: one source file per
|
|
190
|
+
* controller, top-level export name matches the file.
|
|
191
|
+
*/
|
|
192
|
+
function project(module, entry, where) {
|
|
193
|
+
if (!module) {
|
|
194
|
+
throw new RuntimeError("ERR_CONTROLLER_INVALID", `napi module from ${where} is empty`);
|
|
195
|
+
}
|
|
196
|
+
if (!entry) {
|
|
197
|
+
if (!module.create && !module.register) {
|
|
198
|
+
throw new RuntimeError("ERR_CONTROLLER_INVALID", `pkg:cargo controller at ${where} exports neither create nor register`);
|
|
113
199
|
}
|
|
114
|
-
_napiModuleCache.set(cacheKey, module);
|
|
115
200
|
return module;
|
|
116
201
|
}
|
|
202
|
+
const sub = module[entry];
|
|
203
|
+
if (!sub) {
|
|
204
|
+
throw new RuntimeError("ERR_CONTROLLER_INVALID", `pkg:cargo controller at ${where}#${entry}: module has no export named "${entry}"`);
|
|
205
|
+
}
|
|
206
|
+
if (!sub.create && !sub.register) {
|
|
207
|
+
throw new RuntimeError("ERR_CONTROLLER_INVALID", `pkg:cargo controller at ${where}#${entry} exports neither create nor register`);
|
|
208
|
+
}
|
|
209
|
+
return sub;
|
|
117
210
|
}
|
|
118
211
|
async function resolveCrateMetadata(cratePath, fallbackName) {
|
|
119
212
|
const result = await execFileAsync("cargo", [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"napi-loader.js","sourceRoot":"","sources":["../../src/controller-loaders/napi-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,YAAY,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAC1C,MAAM,eAAe,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEvD;;;;;;GAMG;AACH,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAElD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QAFR,gBAAW,GAAG,IAAa,CAAC;QAGnC,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;IAC1C,CAAC;CACF;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,gBAAgB,GAAG,IAAI,GAAG,
|
|
1
|
+
{"version":3,"file":"napi-loader.js","sourceRoot":"","sources":["../../src/controller-loaders/napi-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
import { ControllerInstance } from "@telorun/sdk";
|
|
2
|
+
/**
|
|
3
|
+
* Tells the dispatcher (and any UI consumer downstream) which branch the
|
|
4
|
+
* resolver actually took. `npm-install` is the only one that hits the network;
|
|
5
|
+
* the rest are sub-second cache/local lookups, so the CLI uses this to decide
|
|
6
|
+
* whether a "downloading…" line was honest or should be silently dropped.
|
|
7
|
+
*/
|
|
8
|
+
export type NpmResolveSource = "local" | "node_modules" | "npm-install" | "cache";
|
|
9
|
+
export interface NpmLoadResult {
|
|
10
|
+
instance: ControllerInstance;
|
|
11
|
+
source: NpmResolveSource;
|
|
12
|
+
}
|
|
2
13
|
export declare class NpmControllerLoader {
|
|
3
14
|
/**
|
|
4
15
|
* Resolve a `pkg:npm/...` PURL to a controller module instance. Tries, in order:
|
|
5
16
|
* a relative `local_path` qualifier, the workspace's `node_modules`, and finally
|
|
6
17
|
* an isolated install under `~/.cache/telo/npm/<hash>`.
|
|
7
18
|
*/
|
|
8
|
-
load(purl: string, baseUri: string): Promise<
|
|
19
|
+
load(purl: string, baseUri: string): Promise<NpmLoadResult>;
|
|
9
20
|
private ensureNpmPackageInstalled;
|
|
10
21
|
private getPackageName;
|
|
11
22
|
private getInstalledPackageRoot;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"npm-loader.d.ts","sourceRoot":"","sources":["../../src/controller-loaders/npm-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAgBlD,qBAAa,mBAAmB;IAC9B;;;;OAIG;IACG,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"npm-loader.d.ts","sourceRoot":"","sources":["../../src/controller-loaders/npm-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAgBlD;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,cAAc,GAAG,aAAa,GAAG,OAAO,CAAC;AAElF,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,qBAAa,mBAAmB;IAC9B;;;;OAIG;IACG,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;YAiDnD,yBAAyB;IAuCvC,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,uBAAuB;YAKjB,mBAAmB;YAanB,mBAAmB;IAuEjC,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,wBAAwB;YAgClB,iBAAiB;YAmBjB,iBAAiB;YAejB,UAAU;CAQzB"}
|
|
@@ -23,6 +23,7 @@ export class NpmControllerLoader {
|
|
|
23
23
|
const cacheKey = createHash("sha256").update(purl).digest("hex").slice(0, 12);
|
|
24
24
|
const installDir = path.join(npmCacheRoot, cacheKey);
|
|
25
25
|
let packageRoot;
|
|
26
|
+
let source;
|
|
26
27
|
const isLocalManifest = baseUri && !baseUri.startsWith("http://") && !baseUri.startsWith("https://");
|
|
27
28
|
if (localPath && isLocalManifest) {
|
|
28
29
|
const baseUriPath = baseUri.startsWith("file://") ? baseUri.slice("file://".length) : baseUri;
|
|
@@ -30,14 +31,16 @@ export class NpmControllerLoader {
|
|
|
30
31
|
const resolvedLocalPath = path.resolve(manifestDir, localPath);
|
|
31
32
|
if (await this.pathExists(resolvedLocalPath)) {
|
|
32
33
|
packageRoot = resolvedLocalPath;
|
|
34
|
+
source = "local";
|
|
33
35
|
}
|
|
34
36
|
else {
|
|
35
37
|
const nodeModulesPath = await this.findInNodeModules(`${namespace}/${name}`);
|
|
36
38
|
if (nodeModulesPath) {
|
|
37
39
|
packageRoot = nodeModulesPath;
|
|
40
|
+
source = "node_modules";
|
|
38
41
|
}
|
|
39
42
|
else {
|
|
40
|
-
await this.ensureNpmPackageInstalled(installDir, `${namespace}/${name}@${versionSpec}`);
|
|
43
|
+
source = await this.ensureNpmPackageInstalled(installDir, `${namespace}/${name}@${versionSpec}`);
|
|
41
44
|
packageRoot = this.getInstalledPackageRoot(installDir, `${namespace}/${name}`);
|
|
42
45
|
}
|
|
43
46
|
}
|
|
@@ -46,9 +49,10 @@ export class NpmControllerLoader {
|
|
|
46
49
|
const nodeModulesPath = await this.findInNodeModules(`${namespace}/${name}`);
|
|
47
50
|
if (nodeModulesPath) {
|
|
48
51
|
packageRoot = nodeModulesPath;
|
|
52
|
+
source = "node_modules";
|
|
49
53
|
}
|
|
50
54
|
else {
|
|
51
|
-
await this.ensureNpmPackageInstalled(installDir, `${namespace}/${name}@${versionSpec}`);
|
|
55
|
+
source = await this.ensureNpmPackageInstalled(installDir, `${namespace}/${name}@${versionSpec}`);
|
|
52
56
|
packageRoot = this.getInstalledPackageRoot(installDir, `${namespace}/${name}`);
|
|
53
57
|
}
|
|
54
58
|
}
|
|
@@ -57,7 +61,7 @@ export class NpmControllerLoader {
|
|
|
57
61
|
if (!instance || (!instance.create && !instance.register)) {
|
|
58
62
|
throw new Error(`Invalid controller loaded from "${purl}": missing create or register function`);
|
|
59
63
|
}
|
|
60
|
-
return instance;
|
|
64
|
+
return { instance, source };
|
|
61
65
|
}
|
|
62
66
|
async ensureNpmPackageInstalled(installDir, packageSpec) {
|
|
63
67
|
const packageName = this.getPackageName(packageSpec.startsWith(".") || path.isAbsolute(packageSpec)
|
|
@@ -66,7 +70,7 @@ export class NpmControllerLoader {
|
|
|
66
70
|
const packageRoot = this.getInstalledPackageRoot(installDir, packageName);
|
|
67
71
|
const packageJsonPath = path.join(packageRoot, "package.json");
|
|
68
72
|
if (await this.pathExists(packageJsonPath)) {
|
|
69
|
-
return;
|
|
73
|
+
return "cache";
|
|
70
74
|
}
|
|
71
75
|
await fs.mkdir(installDir, { recursive: true });
|
|
72
76
|
const rootPackageJson = path.join(installDir, "package.json");
|
|
@@ -84,6 +88,7 @@ export class NpmControllerLoader {
|
|
|
84
88
|
packageSpec,
|
|
85
89
|
];
|
|
86
90
|
await execFileAsync("npm", args);
|
|
91
|
+
return "npm-install";
|
|
87
92
|
}
|
|
88
93
|
getPackageName(packageSpec) {
|
|
89
94
|
if (packageSpec.startsWith("@")) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"npm-loader.js","sourceRoot":"","sources":["../../src/controller-loaders/npm-loader.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjC,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;AAC7B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc;IAC1C,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC1C,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AACzC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AACjD,MAAM,KAAK,GAAG,OAAQ,UAAkB,CAAC,GAAG,KAAK,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"npm-loader.js","sourceRoot":"","sources":["../../src/controller-loaders/npm-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { ControllerContext, ResourceContext, ResourceInstance, RuntimeResource } from "@telorun/sdk";
|
|
2
|
-
import { ControllerLoader } from "../../controller-loader.js";
|
|
3
2
|
type ResourceDefinitionResource = RuntimeResource & {
|
|
4
3
|
kind: "Telo.Definition";
|
|
5
4
|
metadata: {
|
|
@@ -17,9 +16,8 @@ type ResourceDefinitionResource = RuntimeResource & {
|
|
|
17
16
|
*/
|
|
18
17
|
declare class ResourceDefinition implements ResourceInstance {
|
|
19
18
|
readonly resource: ResourceDefinitionResource;
|
|
20
|
-
private controllerLoader;
|
|
21
19
|
readonly kind: "ResourceDefinition";
|
|
22
|
-
constructor(resource: ResourceDefinitionResource
|
|
20
|
+
constructor(resource: ResourceDefinitionResource);
|
|
23
21
|
init(ctx: ResourceContext): Promise<void>;
|
|
24
22
|
}
|
|
25
23
|
export declare function register(ctx: ControllerContext): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-definition-controller.d.ts","sourceRoot":"","sources":["../../../src/controllers/resource-definition/resource-definition-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,eAAe,EAChB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"resource-definition-controller.d.ts","sourceRoot":"","sources":["../../../src/controllers/resource-definition/resource-definition-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,eAAe,EAChB,MAAM,cAAc,CAAC;AAKtB,KAAK,0BAA0B,GAAG,eAAe,GAAG;IAClD,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,EAAE;QACR,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CAC7B,CAAC;AAEF;;;GAGG;AACH,cAAM,kBAAmB,YAAW,gBAAgB;IAGtC,QAAQ,CAAC,QAAQ,EAAE,0BAA0B;IAFzD,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAwB;gBAEtC,QAAQ,EAAE,0BAA0B;IAEnD,IAAI,CAAC,GAAG,EAAE,eAAe;CA+BhC;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CAErD;AAED,wBAAsB,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAW7F;AAED,eAAO,MAAM,MAAM;;;CAGlB,CAAC"}
|
|
@@ -6,9 +6,8 @@ import { createTemplateController } from "./resource-template-controller.js";
|
|
|
6
6
|
* Validates incoming definitions against schema and maintains definition metadata
|
|
7
7
|
*/
|
|
8
8
|
class ResourceDefinition {
|
|
9
|
-
constructor(resource
|
|
9
|
+
constructor(resource) {
|
|
10
10
|
this.resource = resource;
|
|
11
|
-
this.controllerLoader = controllerLoader;
|
|
12
11
|
this.kind = "ResourceDefinition";
|
|
13
12
|
}
|
|
14
13
|
async init(ctx) {
|
|
@@ -18,17 +17,17 @@ class ResourceDefinition {
|
|
|
18
17
|
await ctx.registerController(this.resource.metadata.module, this.resource.metadata.name, controllerInstance);
|
|
19
18
|
return;
|
|
20
19
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
20
|
+
// The loader owns ControllerLoading / ControllerLoaded / ControllerLoadFailed
|
|
21
|
+
// emission so it can fire one event per attempted candidate (env-missing
|
|
22
|
+
// fallback chains), and so the payload can include the actually-picked PURL,
|
|
23
|
+
// which branch resolved it (`source`), and timing — none of which are known
|
|
24
|
+
// here at the call site.
|
|
25
|
+
const loader = new ControllerLoader({
|
|
26
|
+
emit: (e) => ctx.emit(e.name, e.payload),
|
|
27
|
+
});
|
|
28
|
+
const controllerInstance = await loader.load(this.resource.controllers, this.resource.metadata.source, ctx.getControllerPolicy());
|
|
29
|
+
ctx.registerDefinition(this.resource);
|
|
30
|
+
await ctx.registerController(this.resource.metadata.module, this.resource.metadata.name, controllerInstance);
|
|
32
31
|
}
|
|
33
32
|
}
|
|
34
33
|
export function register(ctx) {
|
|
@@ -41,7 +40,7 @@ export async function create(resource, ctx) {
|
|
|
41
40
|
}
|
|
42
41
|
// Return a fully-formed ResourceDefinition instance
|
|
43
42
|
const definition = resource;
|
|
44
|
-
return new ResourceDefinition(definition
|
|
43
|
+
return new ResourceDefinition(definition);
|
|
45
44
|
}
|
|
46
45
|
export const schema = {
|
|
47
46
|
type: "object",
|