@telorun/kernel 0.84.0 → 0.86.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 (64) hide show
  1. package/dist/bundle/module-artifact.d.ts +1 -1
  2. package/dist/bundle/module-artifact.d.ts.map +1 -1
  3. package/dist/bundle/module-artifact.js +3 -3
  4. package/dist/bundle/module-artifact.js.map +1 -1
  5. package/dist/controller-loaders/bundle-loader.d.ts +5 -5
  6. package/dist/controller-loaders/bundle-loader.js +7 -7
  7. package/dist/controller-loaders/bundle-loader.js.map +1 -1
  8. package/dist/evaluation-context.d.ts +158 -25
  9. package/dist/evaluation-context.d.ts.map +1 -1
  10. package/dist/evaluation-context.js +234 -44
  11. package/dist/evaluation-context.js.map +1 -1
  12. package/dist/index.d.ts +1 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/kernel.d.ts +60 -5
  17. package/dist/kernel.d.ts.map +1 -1
  18. package/dist/kernel.js +256 -9
  19. package/dist/kernel.js.map +1 -1
  20. package/dist/manifest-sources/local-manifest-cache-source.d.ts +6 -6
  21. package/dist/manifest-sources/local-manifest-cache-source.d.ts.map +1 -1
  22. package/dist/manifest-sources/local-manifest-cache-source.js +11 -12
  23. package/dist/manifest-sources/local-manifest-cache-source.js.map +1 -1
  24. package/dist/module-context.d.ts +31 -1
  25. package/dist/module-context.d.ts.map +1 -1
  26. package/dist/module-context.js +41 -1
  27. package/dist/module-context.js.map +1 -1
  28. package/dist/reconcile.d.ts +42 -0
  29. package/dist/reconcile.d.ts.map +1 -0
  30. package/dist/reconcile.js +58 -0
  31. package/dist/reconcile.js.map +1 -0
  32. package/dist/resource-edges.d.ts +58 -0
  33. package/dist/resource-edges.d.ts.map +1 -0
  34. package/dist/resource-edges.js +110 -0
  35. package/dist/resource-edges.js.map +1 -0
  36. package/dist/runtime-seam.d.ts.map +1 -1
  37. package/dist/runtime-seam.js +1 -2
  38. package/dist/runtime-seam.js.map +1 -1
  39. package/dist/transports/http-transport.d.ts +37 -0
  40. package/dist/transports/http-transport.d.ts.map +1 -0
  41. package/dist/transports/http-transport.js +168 -0
  42. package/dist/transports/http-transport.js.map +1 -0
  43. package/dist/transports/transport-registry.d.ts +13 -14
  44. package/dist/transports/transport-registry.d.ts.map +1 -1
  45. package/dist/transports/transport-registry.js +17 -24
  46. package/dist/transports/transport-registry.js.map +1 -1
  47. package/package.json +3 -3
  48. package/src/bundle/module-artifact.ts +2 -3
  49. package/src/controller-loaders/bundle-loader.ts +7 -7
  50. package/src/evaluation-context.ts +257 -53
  51. package/src/index.ts +1 -1
  52. package/src/kernel.ts +314 -12
  53. package/src/manifest-sources/local-manifest-cache-source.ts +9 -16
  54. package/src/module-context.ts +41 -1
  55. package/src/reconcile.ts +83 -0
  56. package/src/resource-edges.ts +114 -0
  57. package/src/runtime-seam.ts +1 -2
  58. package/src/transports/http-transport.ts +209 -0
  59. package/src/transports/transport-registry.ts +17 -24
  60. package/dist/transports/registry-transport.d.ts +0 -41
  61. package/dist/transports/registry-transport.d.ts.map +0 -1
  62. package/dist/transports/registry-transport.js +0 -282
  63. package/dist/transports/registry-transport.js.map +0 -1
  64. package/src/transports/registry-transport.ts +0 -339
@@ -0,0 +1,114 @@
1
+ /**
2
+ * What the create-time reference edges tell us about a set of resources.
3
+ *
4
+ * The edges themselves are captured by `collectResourceRefs` and projected onto
5
+ * local names by `localDependencyNames` (both in `evaluation-context.ts`, beside
6
+ * the init loop that records them). This module is the two questions asked of
7
+ * that record afterwards, and they are the same question read in opposite
8
+ * directions:
9
+ *
10
+ * - **Forward**, for teardown: in what order may these unwind, so that a
11
+ * consumer's inverses run while what it holds is still alive.
12
+ * - **Reverse**, for reconciliation: if these resources are about to become
13
+ * invalid, who else is holding one and therefore becomes invalid too.
14
+ *
15
+ * Both read `Map<consumer, provider names>` and neither knows what a resource
16
+ * is, which is what keeps them testable without a kernel.
17
+ */
18
+
19
+ /** A resource's outgoing edges: the local names it holds. */
20
+ export type DependencyMap = ReadonlyMap<string, readonly string[]>;
21
+
22
+ /**
23
+ * Order resources so that a consumer is torn down before everything it holds.
24
+ *
25
+ * The caller's order is the TIEBREAK, not the rule. Reverse insertion is
26
+ * already a valid reverse-topological order for every edge Phase-5 injection
27
+ * resolves, because the init loop defers a resource whose refs are unresolved
28
+ * (`ERR_LOCAL_REF_PENDING`) and so cannot insert a consumer before its
29
+ * provider. What this adds is the edges that never pass through injection — a
30
+ * controller resolving a sibling by name inside `init()` — where insertion
31
+ * order says nothing.
32
+ *
33
+ * A cycle emits the first unordered entry and continues: teardown must always
34
+ * run to completion, so an unorderable set degrades to the caller's order
35
+ * rather than raising.
36
+ */
37
+ export function reverseTopologicalOrder<T>(
38
+ entries: ReadonlyArray<readonly [string, T]>,
39
+ nameOf: (value: T) => string,
40
+ dependenciesOf: (name: string) => readonly string[] | undefined,
41
+ ): Array<readonly [string, T]> {
42
+ const indexByName = new Map<string, number>();
43
+ entries.forEach(([, value], index) => indexByName.set(nameOf(value), index));
44
+
45
+ // One edge per (consumer, provider): the provider waits for the consumer.
46
+ const providersOf: number[][] = entries.map(() => []);
47
+ const waiting: number[] = entries.map(() => 0);
48
+ entries.forEach(([, value], consumer) => {
49
+ for (const dependency of dependenciesOf(nameOf(value)) ?? []) {
50
+ const provider = indexByName.get(dependency);
51
+ if (provider === undefined || provider === consumer) continue;
52
+ providersOf[consumer]!.push(provider);
53
+ waiting[provider]! += 1;
54
+ }
55
+ });
56
+
57
+ const ordered: Array<readonly [string, T]> = [];
58
+ const emitted: boolean[] = entries.map(() => false);
59
+ for (let count = 0; count < entries.length; count++) {
60
+ let pick = entries.findIndex((_, i) => !emitted[i] && waiting[i] === 0);
61
+ if (pick < 0) pick = entries.findIndex((_, i) => !emitted[i]);
62
+ emitted[pick] = true;
63
+ ordered.push(entries[pick]!);
64
+ for (const provider of providersOf[pick]!) waiting[provider]! -= 1;
65
+ }
66
+ return ordered;
67
+ }
68
+
69
+ /**
70
+ * Every resource that becomes invalid when `seeds` do: the seeds themselves, and
71
+ * everything that transitively HOLDS one of them.
72
+ *
73
+ * A holder has to go with what it holds because it is holding the instance
74
+ * itself — Phase-5 injection wrote a live object into its reference slot, and
75
+ * rebuilding the target leaves the holder pointing at an object nothing will
76
+ * ever call again. There is no version of this where the holder keeps running,
77
+ * which is why replacing one resource restarts everything above it. That is a
78
+ * cost to state rather than a defect to fix: editing a connection's declaration
79
+ * restarts what uses it.
80
+ *
81
+ * **Exact over the DECLARED edge set, and only that.** An edge exists here when
82
+ * a reference slot named the target, or when a CEL expression read it. A
83
+ * controller that resolves a sibling by NAME instead has a real dependency no
84
+ * walk of the manifest can see; those resolutions are recorded separately as
85
+ * they happen (`opaquelyRead`), and a caller whose closure reaches one has to
86
+ * escalate rather than trust this answer.
87
+ *
88
+ * A cycle is not a special case: the walk visits each name once.
89
+ */
90
+ export function impactClosure(seeds: Iterable<string>, dependencies: DependencyMap): Set<string> {
91
+ // Reversed once per call rather than maintained: the map moves on every
92
+ // create, this is asked once per reconciliation, and an index kept in step
93
+ // with a mutating map is a second source of truth.
94
+ const holdersOf = new Map<string, string[]>();
95
+ for (const [consumer, providers] of dependencies) {
96
+ for (const provider of providers) {
97
+ const held = holdersOf.get(provider);
98
+ if (held) held.push(consumer);
99
+ else holdersOf.set(provider, [consumer]);
100
+ }
101
+ }
102
+
103
+ const impacted = new Set<string>();
104
+ const queue = [...seeds];
105
+ while (queue.length > 0) {
106
+ const name = queue.pop()!;
107
+ if (impacted.has(name)) continue;
108
+ impacted.add(name);
109
+ for (const holder of holdersOf.get(name) ?? []) {
110
+ if (!impacted.has(holder)) queue.push(holder);
111
+ }
112
+ }
113
+ return impacted;
114
+ }
@@ -167,7 +167,6 @@ export class KernelRuntimeSeam implements RuntimeSeam {
167
167
  stdout: stdout.writable,
168
168
  stderr: stderr.writable,
169
169
  sources: [...this.kernel.injectedSources],
170
- registryUrl: this.kernel.registryUrl,
171
170
  });
172
171
 
173
172
  // A child that fails to load is not an exception on this side: the caller
@@ -223,7 +222,7 @@ export class KernelRuntimeSeam implements RuntimeSeam {
223
222
  // rather than the kernel's own loader because a checked manifest is often
224
223
  // deliberately broken and has no business entering the running kernel's
225
224
  // parse cache.
226
- const loader = new Loader(defaultTransportRegistry(this.kernel.registryUrl).sources(), {
225
+ const loader = new Loader(defaultTransportRegistry().sources(), {
227
226
  celHandlers: nodeCelHandlers,
228
227
  });
229
228
  for (const injected of this.kernel.injectedSources) {
@@ -0,0 +1,209 @@
1
+ import {
2
+ DEFAULT_MANIFEST_FILENAME,
3
+ HttpSource,
4
+ sha256Base64Url,
5
+ splitIntegrity,
6
+ type ArtifactLayer,
7
+ type ManifestCacheCoords,
8
+ type ManifestSource,
9
+ } from "@telorun/analyzer";
10
+ import { fetchOrThrow } from "@telorun/sdk";
11
+ import { createHash } from "crypto";
12
+
13
+ import type { PayloadFile } from "../bundle/files-integrity.js";
14
+ import { assertPublicEgress } from "./egress-guard.js";
15
+ import type {
16
+ PayloadLayer,
17
+ PublishBundle,
18
+ PublishOptions,
19
+ PublishResult,
20
+ Transport,
21
+ } from "./transport.js";
22
+
23
+ const QUERY_HASH_LENGTH = 12;
24
+
25
+ /** Mirror `HttpSource.read`'s `fetchUrl` derivation: when the URL does not
26
+ * already point at a YAML file, append `/telo.yaml`, so a raw import URL and
27
+ * the canonical source it resolves to map to the same cache path. */
28
+ function normalizePathname(rawUrl: string, parsed: URL): string {
29
+ let pathname = parsed.pathname;
30
+ if (!rawUrl.includes(".yaml")) {
31
+ pathname = pathname.endsWith("/")
32
+ ? `${pathname}${DEFAULT_MANIFEST_FILENAME}`
33
+ : `${pathname}/${DEFAULT_MANIFEST_FILENAME}`;
34
+ }
35
+ return pathname;
36
+ }
37
+
38
+ /** Short hash of `search + hash` so two URLs that differ only in query /
39
+ * fragment do not collide at the same cache path. */
40
+ function disambiguatePath(pathname: string, search: string, hash: string): string {
41
+ if (!search && !hash) return pathname;
42
+ const digest = createHash("sha256")
43
+ .update(search + hash)
44
+ .digest("hex")
45
+ .slice(0, QUERY_HASH_LENGTH);
46
+ const dotIdx = pathname.lastIndexOf(".");
47
+ const slashIdx = pathname.lastIndexOf("/");
48
+ const ext = dotIdx > slashIdx ? pathname.slice(dotIdx) : "";
49
+ const base = pathname.slice(0, pathname.length - ext.length);
50
+ return `${base}.${digest}${ext}`;
51
+ }
52
+
53
+ /** The transport for direct `https://…` (and `http://`) module URLs. Its
54
+ * resolution `source` composes the browser-safe `HttpSource` from `analyzer`;
55
+ * the Node-only management methods live here. This is the fallback transport
56
+ * for any ref that carries no owning scheme, so `oci://` (or a future `s3://`)
57
+ * never falls through to it — those refs are claimed by their own transport's
58
+ * `supports()`.
59
+ *
60
+ * A URL addresses exactly one file, so it names no enumerable version: this
61
+ * transport publishes nothing, lists no versions, and has no `@version` segment
62
+ * to bump. What it does own is reading, hashing and caching those bytes. */
63
+ export class HttpTransport implements Transport {
64
+ private readonly httpSource: HttpSource;
65
+ readonly source: ManifestSource;
66
+
67
+ constructor() {
68
+ this.httpSource = new HttpSource();
69
+ this.source = {
70
+ supports: (url) => this.supports(url),
71
+ read: async (url) => {
72
+ // The browser-safe source does the fetch; the Node-side egress policy
73
+ // is enforced here, on the host the read will actually hit.
74
+ await assertPublicEgress(url);
75
+ return this.httpSource.read(url);
76
+ },
77
+ resolveRelative: (base, relative) => this.httpSource.resolveRelative(base, relative),
78
+ };
79
+ }
80
+
81
+ supports(ref: string): boolean {
82
+ const { base } = splitIntegrity(ref);
83
+ return base.startsWith("http://") || base.startsWith("https://");
84
+ }
85
+
86
+ cacheCoords(ref: string): ManifestCacheCoords | null {
87
+ const url = splitIntegrity(ref).base;
88
+ if (!url.startsWith("http://") && !url.startsWith("https://")) return null;
89
+
90
+ let parsed: URL;
91
+ try {
92
+ parsed = new URL(url);
93
+ } catch {
94
+ return null;
95
+ }
96
+ const pathname = normalizePathname(url, parsed);
97
+
98
+ // `url` subtree, query-hash suffix on collision. No version segment: a URL
99
+ // addresses exactly one file, and the version it declares lives inside
100
+ // bytes the cache maps paths without.
101
+ const cleanPath = pathname.startsWith("/") ? pathname.slice(1) : pathname;
102
+ const segments = disambiguatePath(cleanPath, parsed.search, parsed.hash).split("/");
103
+ const file = segments.pop();
104
+ if (!file) return null;
105
+ return { transport: "url", host: parsed.host, path: segments.join("/"), file };
106
+ }
107
+
108
+ async listVersions(): Promise<string[] | null> {
109
+ // A direct `https://` URL has no version-list endpoint.
110
+ return null;
111
+ }
112
+
113
+ refVersion(): string | null {
114
+ // A direct `https://` URL has no version segment to bump.
115
+ return null;
116
+ }
117
+
118
+ withVersion(ref: string): string {
119
+ throw new Error(
120
+ `cannot set a version on '${ref}': a URL addresses one file and carries no version segment.`,
121
+ );
122
+ }
123
+
124
+ /** Mirrors the source's fetch-URL derivation: the URL points at (or contains)
125
+ * the YAML file. `null` when this transport does not own the ref's shape. */
126
+ private manifestUrl(ref: string): string | null {
127
+ const { base } = splitIntegrity(ref);
128
+ if (!base.startsWith("http://") && !base.startsWith("https://")) return null;
129
+ return base.includes(".yaml") ? base : `${base}/${DEFAULT_MANIFEST_FILENAME}`;
130
+ }
131
+
132
+ async digest(ref: string): Promise<string | null> {
133
+ // The digest is Telo's canonical hash over the `telo.yaml` bytes — the same
134
+ // value `manifestHash` returns, but absent-is-null rather than a throw.
135
+ const fetchUrl = this.manifestUrl(ref);
136
+ if (!fetchUrl) return null;
137
+ await assertPublicEgress(fetchUrl);
138
+ const res = await fetchOrThrow(fetchUrl, undefined, { operation: "Module manifest read" });
139
+ if (res.status === 404) return null;
140
+ if (!res.ok) {
141
+ throw new Error(`${fetchUrl} returned ${res.status} ${res.statusText}`);
142
+ }
143
+ const bytes = new Uint8Array(await res.arrayBuffer());
144
+ return `sha256-${await sha256Base64Url(bytes)}`;
145
+ }
146
+
147
+ /** Hashes the **raw response bytes**, which is exactly what `verifiedFetch`
148
+ * checks an inline `#sha256-…` pin against on the read path. */
149
+ async manifestHash(ref: string): Promise<string> {
150
+ const fetchUrl = this.manifestUrl(ref);
151
+ if (!fetchUrl) {
152
+ throw new Error(`cannot hash non-remote import '${ref}'`);
153
+ }
154
+ await assertPublicEgress(fetchUrl);
155
+ const res = await fetchOrThrow(fetchUrl, undefined, { operation: "Module manifest hash" });
156
+ if (!res.ok) {
157
+ throw new Error(`fetch ${fetchUrl}: ${res.status} ${res.statusText}`);
158
+ }
159
+ const bytes = new Uint8Array(await res.arrayBuffer());
160
+ return `sha256-${await sha256Base64Url(bytes)}`;
161
+ }
162
+
163
+ /** Layered artifacts are an OCI concept — a module reached over a plain URL is
164
+ * manifest-only, and its controllers come from npm. */
165
+ async fetchLayer(ref: string, blobDigest: string): Promise<PayloadFile[]> {
166
+ throw new Error(
167
+ `Cannot fetch layer ${blobDigest} of ${ref}: a plain URL serves the manifest only. ` +
168
+ `A module with a bundled payload is published as an OCI artifact (oci://host/repo).`,
169
+ );
170
+ }
171
+
172
+ async layerIndex(layers: readonly PayloadLayer[]): Promise<ArtifactLayer[]> {
173
+ // Same boundary `fetchLayer` and `publish` draw: a plain URL serves the
174
+ // manifest only, so it frames no layer and can name no blob. An empty set is
175
+ // not a payload, so it answers rather than throws — a manifest-only module
176
+ // builds its payload through this transport during analysis.
177
+ if (layers.every((layer) => layer.files.length === 0)) return [];
178
+ throw new Error(
179
+ "A plain URL serves the manifest only, so it cannot index payload layers. " +
180
+ "A module with a bundled payload is published as an OCI artifact (oci://host/repo).",
181
+ );
182
+ }
183
+
184
+ async publish(
185
+ destination: string,
186
+ bundle: PublishBundle,
187
+ opts: PublishOptions = {},
188
+ ): Promise<PublishResult> {
189
+ // `telo publish` rejects a non-OCI destination up front, so this is only a
190
+ // guard for a direct programmatic call.
191
+ throw new Error(
192
+ "Publishing over HTTP has been removed. Publish to an OCI registry " +
193
+ "(oci://host/repo) instead.",
194
+ );
195
+ }
196
+
197
+ canonicalizeSiblingRef(destination: string, relativeSource: string, version: string): string {
198
+ // Canonicalizing a sibling is publish-path work, and this transport does not
199
+ // publish — so it refuses here for the same reason `publish` does, rather
200
+ // than computing a ref nothing could ever push. Silence would be worse than
201
+ // useless: an `https://host/` destination has no path to resolve `../lib`
202
+ // beside, so joining anyway yields a ref one segment short with no error.
203
+ throw new Error(
204
+ `Cannot canonicalize the relative import '${relativeSource}' against '${destination}': ` +
205
+ `publishing over plain HTTP has been removed. Publish to an OCI registry ` +
206
+ `(oci://host/repo) instead.`,
207
+ );
208
+ }
209
+ }
@@ -1,8 +1,8 @@
1
1
  import type { ManifestCacheCoords, ManifestSource } from "@telorun/analyzer";
2
2
 
3
3
  import type { PayloadFile } from "../bundle/files-integrity.js";
4
+ import { HttpTransport } from "./http-transport.js";
4
5
  import { OciTransport } from "./oci/oci-transport.js";
5
- import { RegistryTransport } from "./registry-transport.js";
6
6
  import type {
7
7
  PublishBundle,
8
8
  PublishOptions,
@@ -12,9 +12,9 @@ import type {
12
12
 
13
13
  /** Dispatches ref-scheme-specific operations to the transport that owns a ref.
14
14
  * The loader, cache source, `upgrade`, and `publish` consult this instead of
15
- * branching on ref shape. `RegistryTransport` is always last so it is the
16
- * fallback for bare / `https` refs, and a scheme-owning transport (OCI, later
17
- * S3) claims its refs via `supports()` before the fallback is reached. */
15
+ * branching on ref shape. `HttpTransport` is always last so it is the fallback
16
+ * for plain `https` refs, and a scheme-owning transport (OCI, later S3) claims
17
+ * its refs via `supports()` before the fallback is reached. */
18
18
  export class TransportRegistry {
19
19
  constructor(private readonly transports: Transport[]) {}
20
20
 
@@ -73,27 +73,20 @@ export class TransportRegistry {
73
73
  }
74
74
 
75
75
  /** The default transport set. Scheme-owning transports come first; the
76
- * `RegistryTransport` is last, the fallback for bare / `https` refs. OCI (and
77
- * later S3) claim their `oci://` / `s3://` refs before the fallback is reached. */
78
- export function defaultTransports(registryUrl?: string): Transport[] {
79
- return [new OciTransport(), new RegistryTransport(registryUrl)];
76
+ * `HttpTransport` is last, the fallback for plain `https` refs. OCI (and later
77
+ * S3) claim their `oci://` / `s3://` refs before the fallback is reached. */
78
+ export function defaultTransports(): Transport[] {
79
+ return [new OciTransport(), new HttpTransport()];
80
80
  }
81
81
 
82
- const defaultRegistryCache = new Map<string, TransportRegistry>();
82
+ let defaultRegistry: TransportRegistry | undefined;
83
83
 
84
- /** A `TransportRegistry` seeded with {@link defaultTransports}, memoized per
85
- * `registryUrl`. The default transports hold no per-call state, so one shared
86
- * instance per registry URL is safe — and avoids re-instantiating the whole set
87
- * on hot paths like `cachePathForCanonical`. It is also what gives
88
- * `OciTransport`'s per-instance read-client pool a process-wide lifetime here,
89
- * so the bearer-token cache survives across operations without the pool having
90
- * to be global. */
91
- export function defaultTransportRegistry(registryUrl?: string): TransportRegistry {
92
- const key = registryUrl ?? "";
93
- let cached = defaultRegistryCache.get(key);
94
- if (!cached) {
95
- cached = new TransportRegistry(defaultTransports(registryUrl));
96
- defaultRegistryCache.set(key, cached);
97
- }
98
- return cached;
84
+ /** A `TransportRegistry` seeded with {@link defaultTransports}, memoized. The
85
+ * default transports hold no per-call state, so one shared instance is safe —
86
+ * and avoids re-instantiating the whole set on hot paths like
87
+ * `cachePathForCanonical`. It is also what gives `OciTransport`'s per-instance
88
+ * read-client pool a process-wide lifetime here, so the bearer-token cache
89
+ * survives across operations without the pool having to be global. */
90
+ export function defaultTransportRegistry(): TransportRegistry {
91
+ return (defaultRegistry ??= new TransportRegistry(defaultTransports()));
99
92
  }
@@ -1,41 +0,0 @@
1
- import { type ArtifactLayer, type ManifestCacheCoords, type ManifestSource } from "@telorun/analyzer";
2
- import type { PayloadFile } from "../bundle/files-integrity.js";
3
- import type { PayloadLayer, PublishBundle, PublishOptions, PublishResult, Transport } from "./transport.js";
4
- /** The default HTTP transport: bare `namespace/name@version` registry refs and
5
- * direct `https://…` URLs, resolving against `registry.telo.run` (or a
6
- * configured registry). Its resolution `source` composes the browser-safe
7
- * `RegistrySource` / `HttpSource` from `analyzer`; the Node-only management
8
- * methods live here. This is the fallback transport for any ref that carries
9
- * no owning scheme, so `oci://` (or a future `s3://`) never falls through to
10
- * it — those refs are claimed by their own transport's `supports()`. */
11
- export declare class RegistryTransport implements Transport {
12
- private readonly registryUrl;
13
- private readonly registrySource;
14
- private readonly httpSource;
15
- readonly source: ManifestSource;
16
- constructor(registryUrl?: string);
17
- supports(ref: string): boolean;
18
- cacheCoords(ref: string): ManifestCacheCoords | null;
19
- /** Host of the configured registry, or `null` when the URL is unparseable. */
20
- private registryHost;
21
- listVersions(ref: string): Promise<string[] | null>;
22
- refVersion(ref: string): string | null;
23
- withVersion(ref: string, version: string): string;
24
- /** Mirrors the sources' fetch-URL derivation: a direct URL points at (or
25
- * contains) the YAML file; a bare registry ref folds into the registry
26
- * layout. `null` when this transport does not own the ref's shape. */
27
- private manifestUrl;
28
- digest(ref: string): Promise<string | null>;
29
- /** Hashes the **raw response bytes**, which is exactly what `verifiedFetch`
30
- * checks an inline `#sha256-…` pin against on the read path. */
31
- manifestHash(ref: string): Promise<string>;
32
- /** Layered artifacts are an OCI concept, and the registry origin is read-only
33
- * — nothing has ever published a payload here, so there is no layer to pull.
34
- * A module reached over the registry is manifest-only, and its controllers
35
- * come from npm. */
36
- fetchLayer(ref: string, blobDigest: string): Promise<PayloadFile[]>;
37
- layerIndex(layers: readonly PayloadLayer[]): Promise<ArtifactLayer[]>;
38
- publish(destination: string, bundle: PublishBundle, opts?: PublishOptions): Promise<PublishResult>;
39
- canonicalizeSiblingRef(destination: string, relativeSource: string, version: string): string;
40
- }
41
- //# sourceMappingURL=registry-transport.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"registry-transport.d.ts","sourceRoot":"","sources":["../../src/transports/registry-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAUL,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEhE,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,cAAc,EACd,aAAa,EACb,SAAS,EACV,MAAM,gBAAgB,CAAC;AAkDxB;;;;;;yEAMyE;AACzE,qBAAa,iBAAkB,YAAW,SAAS;IAKrC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAJxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;gBAEH,WAAW,GAAE,MAA6B;IAiBvE,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAK9B,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI;IAwEpD,8EAA8E;IAC9E,OAAO,CAAC,YAAY;IAQd,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;IAoBzD,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAMtC,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAIjD;;2EAEuE;IACvE,OAAO,CAAC,WAAW;IAYb,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAkBjD;qEACiE;IAC3D,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBhD;;;yBAGqB;IACf,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAOnE,UAAU,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAYrE,OAAO,CACX,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,aAAa,EACrB,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,aAAa,CAAC;IAWzB,sBAAsB,CACpB,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,GACd,MAAM;CAwBV"}