@agentxm/registry-client 0.28.4 → 0.28.6
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/src/client.d.ts +10 -0
- package/dist/src/index.d.ts +1 -1
- package/dist/src/remote-client.js +38 -7
- package/package.json +4 -3
package/dist/src/client.d.ts
CHANGED
|
@@ -50,6 +50,11 @@ export interface GetExtensionsByOwnerArgs {
|
|
|
50
50
|
* - `name`: extension name
|
|
51
51
|
* - `version`: specific version to fetch, or `None` for latest
|
|
52
52
|
*/
|
|
53
|
+
/** Bytes received so far and the declared total when the transport reports one. */
|
|
54
|
+
export interface ArchiveDownloadProgress {
|
|
55
|
+
readonly done: number;
|
|
56
|
+
readonly total?: number | undefined;
|
|
57
|
+
}
|
|
53
58
|
export interface GetExtensionPackageArgs {
|
|
54
59
|
readonly owner: Handle;
|
|
55
60
|
readonly type: ExtensionType;
|
|
@@ -57,6 +62,11 @@ export interface GetExtensionPackageArgs {
|
|
|
57
62
|
readonly version: Option.Option<Version | VersionRange>;
|
|
58
63
|
/** Marks an archive read used only to verify compatibility before selection. */
|
|
59
64
|
readonly usagePurpose?: "verification";
|
|
65
|
+
/**
|
|
66
|
+
* Observes archive bytes as they arrive. Called once per received chunk;
|
|
67
|
+
* callers throttle before publishing. Never called for a cache hit.
|
|
68
|
+
*/
|
|
69
|
+
readonly onProgress?: (progress: ArchiveDownloadProgress) => Effect.Effect<void>;
|
|
60
70
|
}
|
|
61
71
|
/**
|
|
62
72
|
* Options for fetching extension index metadata from a registry.
|
package/dist/src/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* @experimental This API is unstable and may change without notice.
|
|
10
10
|
* @packageDocumentation
|
|
11
11
|
*/
|
|
12
|
-
export type { RegistryClient, RegistryExtensionManifest, DiscoverPackageInput, DiscoverPackagesArgs, GetExtensionsByOwnerArgs, GetExtensionsByOwnerResponse, GetExtensionIndexArgs, GetExactExtensionVersionArgs, ExactExtensionVersion, GetExtensionVisibilityArgs, GetExtensionPackageArgs, GetExtensionPackageResponse, PublishExtensionArgs, PublishExtensionResponse, RegistryPublishWarning, PreviewExtensionPublishesArgs, PublishPreviewResult, PublishPreviewTarget, OwnerExistsResponse, ExtensionExistsArgs, ExtensionExistsResponse, ExtensionVisibility, UpdateExtensionVisibilityArgs, } from "./client.js";
|
|
12
|
+
export type { RegistryClient, RegistryExtensionManifest, DiscoverPackageInput, DiscoverPackagesArgs, GetExtensionsByOwnerArgs, GetExtensionsByOwnerResponse, GetExtensionIndexArgs, GetExactExtensionVersionArgs, ExactExtensionVersion, GetExtensionVisibilityArgs, ArchiveDownloadProgress, GetExtensionPackageArgs, GetExtensionPackageResponse, PublishExtensionArgs, PublishExtensionResponse, RegistryPublishWarning, PreviewExtensionPublishesArgs, PublishPreviewResult, PublishPreviewTarget, OwnerExistsResponse, ExtensionExistsArgs, ExtensionExistsResponse, ExtensionVisibility, UpdateExtensionVisibilityArgs, } from "./client.js";
|
|
13
13
|
export { createRegistryClient } from "./client.js";
|
|
14
14
|
export { createLocalRegistryClient } from "./local-client.js";
|
|
15
15
|
export { createRemoteRegistryClient } from "./remote-client.js";
|
|
@@ -9,8 +9,11 @@
|
|
|
9
9
|
* @experimental This API is unstable and may change without notice.
|
|
10
10
|
* @packageDocumentation
|
|
11
11
|
*/
|
|
12
|
+
import * as Headers from "effect/unstable/http/Headers";
|
|
12
13
|
import * as HttpClient from "effect/unstable/http/HttpClient";
|
|
13
14
|
import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";
|
|
15
|
+
import * as MutableRef from "effect/MutableRef";
|
|
16
|
+
import * as Stream from "effect/Stream";
|
|
14
17
|
import * as Effect from "effect/Effect";
|
|
15
18
|
import * as Option from "effect/Option";
|
|
16
19
|
import * as Schema from "effect/Schema";
|
|
@@ -197,6 +200,35 @@ const extensionDeclarationToDiscoveryRef = (value) => {
|
|
|
197
200
|
: { versionRange: value.versionRange }),
|
|
198
201
|
};
|
|
199
202
|
};
|
|
203
|
+
const contentLength = (response) => Option.match(Headers.get(response.headers, "content-length"), {
|
|
204
|
+
onNone: () => undefined,
|
|
205
|
+
onSome: (value) => {
|
|
206
|
+
const parsed = Number(value);
|
|
207
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : undefined;
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
/**
|
|
211
|
+
* Stream one archive body into memory, reporting received bytes per chunk.
|
|
212
|
+
* Non-2xx statuses fail as `HttpClientError` so the caller's mapping keeps
|
|
213
|
+
* the response evidence.
|
|
214
|
+
*/
|
|
215
|
+
const downloadArchive = (http, path, onProgress) => Effect.gen(function* () {
|
|
216
|
+
const response = yield* HttpClient.filterStatusOk(http).execute(HttpClientRequest.get(path));
|
|
217
|
+
const total = contentLength(response);
|
|
218
|
+
const received = MutableRef.make(0);
|
|
219
|
+
const report = onProgress ?? (() => Effect.void);
|
|
220
|
+
const chunks = yield* response.stream.pipe(Stream.tap((chunk) => report({
|
|
221
|
+
done: MutableRef.updateAndGet(received, (done) => done + chunk.byteLength),
|
|
222
|
+
...(total === undefined ? {} : { total }),
|
|
223
|
+
})), Stream.runCollect);
|
|
224
|
+
const archive = new Uint8Array(MutableRef.get(received));
|
|
225
|
+
let offset = 0;
|
|
226
|
+
for (const chunk of chunks) {
|
|
227
|
+
archive.set(chunk, offset);
|
|
228
|
+
offset += chunk.byteLength;
|
|
229
|
+
}
|
|
230
|
+
return archive;
|
|
231
|
+
});
|
|
200
232
|
const registryRequestMetadata = (method, url) => ({
|
|
201
233
|
service: "registry",
|
|
202
234
|
method,
|
|
@@ -216,9 +248,7 @@ const registryRequestMetadata = (method, url) => ({
|
|
|
216
248
|
export const createRemoteRegistryClient = (baseUrl, httpClient, archiveCache, requestPolicy) => {
|
|
217
249
|
const remoteHttpClient = captureRegistryErrorResponseBodies(httpClient.pipe(HttpClient.mapRequest(HttpClientRequest.prependUrl(baseUrl))));
|
|
218
250
|
const client = GeneratedRegistryClient.make(remoteHttpClient);
|
|
219
|
-
const
|
|
220
|
-
transformClient: (baseClient) => Effect.succeed(baseClient.pipe(HttpClient.mapRequest(HttpClientRequest.setHeader("x-agentxm-usage-purpose", "verification")))),
|
|
221
|
-
});
|
|
251
|
+
const verificationHttpClient = remoteHttpClient.pipe(HttpClient.mapRequest(HttpClientRequest.setHeader("x-agentxm-usage-purpose", "verification")));
|
|
222
252
|
const executeRemoteRequest = (effect, args) => executeRegistryRequest(effect, {
|
|
223
253
|
operation: args.operation,
|
|
224
254
|
request: registryRequestMetadata(args.method, new URL(args.path, baseUrl).href),
|
|
@@ -457,12 +487,13 @@ export const createRemoteRegistryClient = (baseUrl, httpClient, archiveCache, re
|
|
|
457
487
|
};
|
|
458
488
|
}
|
|
459
489
|
}
|
|
460
|
-
// Step 3: Download archive
|
|
461
|
-
|
|
462
|
-
const
|
|
490
|
+
// Step 3: Download archive, streaming the body so the caller observes
|
|
491
|
+
// progress as bytes arrive; the transport never decides how often.
|
|
492
|
+
const archivePath = `/v1/extensions/${args.owner}/${pluralizeType(args.type)}/${args.name}/${resolvedEntry.value.version}/archive`;
|
|
493
|
+
const archive = yield* executeRemoteRequest(downloadArchive(args.usagePurpose === "verification" ? verificationHttpClient : remoteHttpClient, archivePath, args.onProgress), {
|
|
463
494
|
operation: "download package archive",
|
|
464
495
|
method: "GET",
|
|
465
|
-
path:
|
|
496
|
+
path: archivePath,
|
|
466
497
|
replaySafety: safe,
|
|
467
498
|
mapError: mapArchiveFetchError,
|
|
468
499
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentxm/registry-client",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.6",
|
|
4
4
|
"description": "AXM registry integration: local and remote registry clients over the generated OpenAPI transport, request policy and retries, typed registry failures, archive cache, and lifecycle administration for the axm CLI. Unstable and unsupported — use the axm.sh CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "FSL-1.1-MIT",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"exports": {
|
|
19
19
|
".": {
|
|
20
20
|
"types": "./dist/src/index.d.ts",
|
|
21
|
+
"axm-source": "./src/index.ts",
|
|
21
22
|
"default": "./dist/src/index.js"
|
|
22
23
|
}
|
|
23
24
|
},
|
|
@@ -38,8 +39,8 @@
|
|
|
38
39
|
"effect": "4.0.0-rc.112",
|
|
39
40
|
"fflate": "^0.8.3",
|
|
40
41
|
"semver": "^7.8.5",
|
|
41
|
-
"@agentxm/extension-model": "^0.28.
|
|
42
|
-
"@agentxm/registry-protocol": "^0.28.
|
|
42
|
+
"@agentxm/extension-model": "^0.28.6",
|
|
43
|
+
"@agentxm/registry-protocol": "^0.28.6"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
46
|
"@effect/openapi-generator": "4.0.0-rc.112",
|