🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@cortexkit/subc-client

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cortexkit/subc-client - npm Package Compare versions

Comparing version
0.1.0
to
0.2.0
+1
-1
package.json
{
"name": "@cortexkit/subc-client",
"version": "0.1.0",
"version": "0.2.0",
"description": "TypeScript client for the subc daemon. Wire-compatible (byte-for-byte) with the Rust subc-transport handshake and subc-protocol envelope.",

@@ -5,0 +5,0 @@ "type": "module",

@@ -41,2 +41,4 @@ // The consumer-facing subc client. Mirrors the canonical pure consumer

const DEFAULT_MANAGED_TARGET_KIND: ManagedRouteKind = "management_surface";
export const SUBC_MODULE_ID_ENV = "SUBC_MODULE_ID";
export const SUBC_LAUNCH_NONCE_ENV = "SUBC_LAUNCH_NONCE";

@@ -56,2 +58,12 @@ export interface BindIdentity {

export interface ConsumerIdentity {
module_id: string;
launch_nonce: string;
}
export interface RouteOpenOptions {
/** Optional override for the consumer identity; by default the SUBC_MODULE_ID and SUBC_LAUNCH_NONCE environment variables are used when both are non-empty. Set null to send route.open without consumer_identity. */
consumerIdentity?: ConsumerIdentity | null;
}
export interface CatalogEntry {

@@ -75,2 +87,4 @@ module_id: string;

targetKind?: ManagedRouteKind;
/** Optional override for the consumer identity; by default the SUBC_MODULE_ID and SUBC_LAUNCH_NONCE environment variables are used when both are non-empty. Set null to send route.open without consumer_identity. */
consumerIdentity?: ConsumerIdentity | null;
}

@@ -89,2 +103,4 @@

drain?: boolean;
/** Consumer identity to use when looking up the route to close; only needed for routes opened with a non-default consumer identity. */
consumerIdentity?: ConsumerIdentity | null;
}

@@ -206,2 +222,3 @@

identity: BindIdentity;
consumerIdentity?: ConsumerIdentity;
channel: number | null;

@@ -260,4 +277,10 @@ generation: number;

/** Open a route to a provider (channel-0 route.open); returns the route channel. */
async routeOpen(target: RouteTarget, identity: BindIdentity): Promise<number> {
const body = this.encode({ op: "route.open", target, identity });
async routeOpen(target: RouteTarget, identity: BindIdentity, opts: RouteOpenOptions = {}): Promise<number> {
const consumerIdentity = routeOpenConsumerIdentity(opts);
const body = this.encode({
op: "route.open",
target,
identity,
...(consumerIdentity ? { consumer_identity: consumerIdentity } : {}),
});
const reply = await this.controlRpc(body);

@@ -389,3 +412,3 @@ const parsed = this.parseJson(reply) as { op: string; route_channel?: number };

): Promise<void> {
const key = routeCacheKey(target, identity);
const key = routeCacheKey(target, identity, routeOpenConsumerIdentity(opts));
const cached = this.routes.get(key);

@@ -600,3 +623,4 @@ if (!cached) return; // never opened / already closed — idempotent no-op.

>;
const key = routeCacheKey(target, identity);
const consumerIdentity = routeOpenConsumerIdentity(opts);
const key = routeCacheKey(target, identity, consumerIdentity);
let cached = this.routes.get(key);

@@ -609,2 +633,3 @@ if (!cached) {

identity,
consumerIdentity,
channel: null,

@@ -642,3 +667,5 @@ generation: 0,

try {
const channel = await this.routeOpen(cached.target, cached.identity);
const channel = await this.routeOpen(cached.target, cached.identity, {
consumerIdentity: cached.consumerIdentity ?? null,
});
// Generation guard: a closeRoute may have flipped the tombstone WHILE this

@@ -898,6 +925,21 @@ // route.open was in flight. If so, close wins — do NOT install the channel

function routeCacheKey(target: Extract<RouteTarget, { kind: ManagedRouteKind }>, identity: BindIdentity): string {
return `${target.kind}\0${target.module_id}\0${identity.project_root}\0${identity.harness}\0${identity.session}`;
function routeCacheKey(
target: Extract<RouteTarget, { kind: ManagedRouteKind }>,
identity: BindIdentity,
consumerIdentity?: ConsumerIdentity,
): string {
const consumerPart = consumerIdentity
? `${consumerIdentity.module_id}\0${consumerIdentity.launch_nonce}`
: "";
return `${target.kind}\0${target.module_id}\0${identity.project_root}\0${identity.harness}\0${identity.session}\0${consumerPart}`;
}
function routeOpenConsumerIdentity(opts: RouteOpenOptions = {}): ConsumerIdentity | undefined {
if (opts.consumerIdentity !== undefined) return opts.consumerIdentity ?? undefined;
const moduleId = process.env[SUBC_MODULE_ID_ENV];
const launchNonce = process.env[SUBC_LAUNCH_NONCE_ENV];
if (!moduleId || !launchNonce) return undefined;
return { module_id: moduleId, launch_nonce: launchNonce };
}
function errorCode(err: unknown): string | undefined {

@@ -904,0 +946,0 @@ if (typeof err === "object" && err !== null && "code" in err) {

@@ -6,2 +6,4 @@ export {

DEFAULT_RECONNECT_BACKOFF,
SUBC_MODULE_ID_ENV,
SUBC_LAUNCH_NONCE_ENV,
isConsumerReconnectTransient,

@@ -12,2 +14,4 @@ connectionFileExists,

type ManagedRouteKind,
type ConsumerIdentity,
type RouteOpenOptions,
type CatalogEntry,

@@ -62,2 +66,3 @@ type RequestOptions,

type BindDecision,
type Principal,
type BindingsInput,

@@ -64,0 +69,0 @@ type CircuitBreakerInput,

@@ -205,2 +205,7 @@ import { Buffer } from "node:buffer";

export type Principal =
| { kind: "reserved"; module_id: string }
| { kind: "direct" }
| { kind: "unverified" };
export interface RouteBindRequest {

@@ -210,2 +215,3 @@ route_channel: number;

identity: BindIdentity;
principal?: Principal;
}

@@ -538,2 +544,3 @@

identity: request.identity as BindIdentity,
principal: request.principal as Principal | undefined,
};

@@ -540,0 +547,0 @@