@qitqode/qitqore 0.0.0-stage → 0.1.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/README.md CHANGED
@@ -1,3 +1,45 @@
1
- # Temporary Holding Version
1
+ # QitQore
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ QitQore is an independent Node.js library for the shared parts of communicating
4
+ with Qortex: bounded HTTP transport, response/error evidence, incremental SSE
5
+ decoding, request-status lookup, and explicitly authorized retry execution.
6
+
7
+ It is not a CLI, agent runtime, authentication store, policy engine, scheduler,
8
+ or billing/settlement system. Importing the package creates no directories,
9
+ reads credentials, changes process settings, or makes network requests.
10
+
11
+ ## Development
12
+
13
+ - Requires Node.js 24 or newer.
14
+ - In this monorepo, `pnpm --dir products/qitqore install --ignore-workspace`
15
+ installs the build-only TypeScript dependency. In a standalone checkout, use
16
+ `pnpm install`.
17
+ - `pnpm test` compiles the package and runs deterministic `node:test` coverage.
18
+ - `npm pack --dry-run` checks the independent package contents. `npm pack`
19
+ builds and tests first.
20
+
21
+ The package has no runtime dependencies. Its sole public entry point is the
22
+ compiled ESM export at `.`.
23
+
24
+ ## Host responsibilities
25
+
26
+ Create a client with an explicit base URL and optional `fetch` implementation.
27
+ Provide credentials and other headers per request; QitQore never reads a
28
+ credential store. Hosts continue to own authorization, grants, leases, budgets,
29
+ operation persistence, tool execution, and settlement.
30
+
31
+ `requestJson` returns response data with status and request-ID evidence.
32
+ `openStream` returns the response body as a cancellable byte stream. Its
33
+ request timeout remains active until the body is consumed, cancelled, or
34
+ errors. Use `SseDecoder` or `iterateSse` when the response uses SSE.
35
+
36
+ `runWithRecovery` never retries based only on an error classifier. The host
37
+ must supply both a retry classifier and an authorization callback for the same
38
+ stable operation ID. It receives whether the prior attempt was accepted,
39
+ produced partial output, or started a side effect. Acceptance, partial output,
40
+ and side effects block replay. Unknown outcomes require affirmative host
41
+ evidence and authorization; an idempotency header alone is not evidence.
42
+
43
+ Errors expose bounded, redacted diagnostic fields and request IDs, not raw
44
+ response bodies or request credentials. Hosts may retain their existing
45
+ product-specific error mappings around these shared primitives.
@@ -0,0 +1,41 @@
1
+ export type QortexErrorCategory = "credentials" | "authorization" | "validation" | "rate-limit" | "gateway" | "server" | "http" | "protocol" | "transport" | "timeout";
2
+ export interface QortexErrorDetails {
3
+ category: QortexErrorCategory;
4
+ message: string;
5
+ code?: string;
6
+ status?: number;
7
+ requestId?: string;
8
+ retryable: boolean;
9
+ }
10
+ export declare class QortexError extends Error {
11
+ readonly category: QortexErrorCategory;
12
+ readonly code?: string;
13
+ readonly status?: number;
14
+ readonly requestId?: string;
15
+ readonly retryable: boolean;
16
+ constructor(details: QortexErrorDetails, options?: {
17
+ cause?: unknown;
18
+ });
19
+ toJSON(): QortexErrorDetails;
20
+ }
21
+ export declare class QortexHttpError extends QortexError {
22
+ constructor(details: QortexErrorDetails, options?: {
23
+ cause?: unknown;
24
+ });
25
+ }
26
+ export declare class QortexTimeoutError extends QortexError {
27
+ constructor(timeoutMs: number, options?: {
28
+ cause?: unknown;
29
+ });
30
+ }
31
+ export declare class QortexTransportError extends QortexError {
32
+ constructor(options?: {
33
+ cause?: unknown;
34
+ });
35
+ }
36
+ export declare class QortexProtocolError extends QortexError {
37
+ constructor(message: string, status?: number, requestId?: string);
38
+ }
39
+ export declare function qortexHttpError(status: number, payload: unknown, headers?: HeadersInit): QortexHttpError;
40
+ export declare function isAbortError(error: unknown): boolean;
41
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAC3B,aAAa,GACb,eAAe,GACf,YAAY,GACZ,YAAY,GACZ,SAAS,GACT,QAAQ,GACR,MAAM,GACN,UAAU,GACV,WAAW,GACX,SAAS,CAAC;AAEd,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB;AAmDD,qBAAa,WAAY,SAAQ,KAAK;IACpC,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;gBAG1B,OAAO,EAAE,kBAAkB,EAC3B,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;IAWnC,MAAM,IAAI,kBAAkB;CAU7B;AAED,qBAAa,eAAgB,SAAQ,WAAW;gBAClC,OAAO,EAAE,kBAAkB,EAAE,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;CAI3E;AAED,qBAAa,kBAAmB,SAAQ,WAAW;gBACrC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;CAYjE;AAED,qBAAa,oBAAqB,SAAQ,WAAW;gBACvC,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;CAY9C;AAED,qBAAa,mBAAoB,SAAQ,WAAW;gBACtC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM;CAWjE;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,WAAW,GACpB,eAAe,CA4CjB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAKpD"}
package/dist/errors.js ADDED
@@ -0,0 +1,163 @@
1
+ const SAFE_CODE = /^[A-Za-z0-9_.:-]{1,128}$/;
2
+ const SAFE_REQUEST_ID = /^[A-Za-z0-9_.:-]{1,160}$/;
3
+ const AUTH_HEADER = /\b(authorization)\s*[:=]\s*(?:bearer|basic)\s+\S+/gi;
4
+ const SECRET_VALUE = /\b(api[-_ ]?key|access[-_ ]?token|refresh[-_ ]?token|token|password|secret)\s*[:=]\s*["']?[^\s,;"'&]+/gi;
5
+ const BEARER_TOKEN = /\b(bearer|basic)\s+[A-Za-z0-9._~+/-]+=*/gi;
6
+ const URL_SECRET = /([?&](?:api[-_]?key|access[-_]?token|refresh[-_]?token|token|secret)=)[^&\s]+/gi;
7
+ const JWT = /\beyJ[A-Za-z0-9_-]*\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g;
8
+ function record(value) {
9
+ return value !== null && typeof value === "object" && !Array.isArray(value)
10
+ ? value
11
+ : undefined;
12
+ }
13
+ function boundedText(value, maxLength) {
14
+ if (typeof value !== "string")
15
+ return undefined;
16
+ const safe = value
17
+ .replace(AUTH_HEADER, "$1: [redacted]")
18
+ .replace(SECRET_VALUE, "$1=[redacted]")
19
+ .replace(BEARER_TOKEN, "$1 [redacted]")
20
+ .replace(URL_SECRET, "$1[redacted]")
21
+ .replace(JWT, "[redacted-token]")
22
+ .replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g, " ")
23
+ .trim()
24
+ .slice(0, maxLength);
25
+ return safe || undefined;
26
+ }
27
+ function safeCode(value) {
28
+ if (typeof value !== "string")
29
+ return undefined;
30
+ const candidate = value.trim();
31
+ if (!SAFE_CODE.test(candidate))
32
+ return undefined;
33
+ // Error codes are useful evidence, but long unstructured identifiers can be
34
+ // API keys or tokens echoed into a server's code field.
35
+ if (candidate.length > 32 &&
36
+ !/^(?:ERR|E_|QORTEX|QLEX|AUTH|GATEWAY|VALIDATION|RATE_LIMIT|HTTP_)/i.test(candidate)) {
37
+ return undefined;
38
+ }
39
+ return candidate;
40
+ }
41
+ function safeRequestId(value) {
42
+ const candidate = value?.trim();
43
+ return candidate && SAFE_REQUEST_ID.test(candidate) ? candidate : undefined;
44
+ }
45
+ export class QortexError extends Error {
46
+ category;
47
+ code;
48
+ status;
49
+ requestId;
50
+ retryable;
51
+ constructor(details, options = {}) {
52
+ super(details.message, options.cause === undefined ? undefined : { cause: options.cause });
53
+ this.name = "QortexError";
54
+ this.category = details.category;
55
+ this.code = details.code;
56
+ this.status = details.status;
57
+ this.requestId = details.requestId;
58
+ this.retryable = details.retryable;
59
+ }
60
+ toJSON() {
61
+ return {
62
+ category: this.category,
63
+ message: this.message,
64
+ ...(this.code ? { code: this.code } : {}),
65
+ ...(this.status === undefined ? {} : { status: this.status }),
66
+ ...(this.requestId ? { requestId: this.requestId } : {}),
67
+ retryable: this.retryable,
68
+ };
69
+ }
70
+ }
71
+ export class QortexHttpError extends QortexError {
72
+ constructor(details, options = {}) {
73
+ super(details, options);
74
+ this.name = "QortexHttpError";
75
+ }
76
+ }
77
+ export class QortexTimeoutError extends QortexError {
78
+ constructor(timeoutMs, options = {}) {
79
+ super({
80
+ category: "timeout",
81
+ code: "QORTEX_REQUEST_TIMEOUT",
82
+ message: `Qortex did not complete the request within ${timeoutMs}ms`,
83
+ retryable: true,
84
+ }, options);
85
+ this.name = "QortexTimeoutError";
86
+ }
87
+ }
88
+ export class QortexTransportError extends QortexError {
89
+ constructor(options = {}) {
90
+ super({
91
+ category: "transport",
92
+ code: "QORTEX_TRANSPORT_ERROR",
93
+ message: "The Qortex request failed before a response was received",
94
+ retryable: true,
95
+ }, options);
96
+ this.name = "QortexTransportError";
97
+ }
98
+ }
99
+ export class QortexProtocolError extends QortexError {
100
+ constructor(message, status, requestId) {
101
+ super({
102
+ category: "protocol",
103
+ code: "QORTEX_PROTOCOL_ERROR",
104
+ message: boundedText(message, 512) ?? "Qortex returned an invalid response",
105
+ ...(status === undefined ? {} : { status }),
106
+ ...(requestId ? { requestId } : {}),
107
+ retryable: false,
108
+ });
109
+ this.name = "QortexProtocolError";
110
+ }
111
+ }
112
+ export function qortexHttpError(status, payload, headers) {
113
+ const outer = record(payload);
114
+ const nested = record(outer?.error);
115
+ const code = safeCode(outer?.code) ??
116
+ safeCode(nested?.code) ??
117
+ (typeof outer?.error === "string" ? safeCode(outer.error) : undefined) ??
118
+ `QORTEX_HTTP_${status}`;
119
+ const message = boundedText(outer?.message, 512) ??
120
+ boundedText(outer?.error_description, 512) ??
121
+ boundedText(nested?.message, 512) ??
122
+ (typeof outer?.error === "string" ? boundedText(outer.error, 512) : undefined) ??
123
+ `Qortex returned HTTP ${status}`;
124
+ const requestHeaders = new Headers(headers);
125
+ const requestId = safeRequestId(requestHeaders.get("x-request-id")) ??
126
+ safeRequestId(requestHeaders.get("request-id")) ??
127
+ safeRequestId(requestHeaders.get("x-qlex-request-id"));
128
+ const envelopeFailure = outer?.success === false;
129
+ let category;
130
+ if (envelopeFailure && status < 400)
131
+ category = "protocol";
132
+ else if (status === 401 ||
133
+ (status === 403 && /credential|authentication|unauthori[sz]ed/i.test(code))) {
134
+ category = "credentials";
135
+ }
136
+ else if (status === 403)
137
+ category = "authorization";
138
+ else if (/gateway|routing|upstream/i.test(code))
139
+ category = "gateway";
140
+ else if (status === 400 || status === 422)
141
+ category = "validation";
142
+ else if (status === 429)
143
+ category = "rate-limit";
144
+ else if (status === 502 || status === 503 || status === 504)
145
+ category = "gateway";
146
+ else if (status >= 500)
147
+ category = "server";
148
+ else
149
+ category = "http";
150
+ return new QortexHttpError({
151
+ category,
152
+ message,
153
+ code,
154
+ status,
155
+ ...(requestId ? { requestId } : {}),
156
+ retryable: status === 408 || status === 425 || status === 429 || status >= 500,
157
+ });
158
+ }
159
+ export function isAbortError(error) {
160
+ return ((error instanceof Error && error.name === "AbortError") ||
161
+ (error instanceof Error && error.name === "TimeoutError"));
162
+ }
163
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { QortexError, QortexHttpError, QortexProtocolError, QortexTimeoutError, QortexTransportError, isAbortError, qortexHttpError, type QortexErrorCategory, type QortexErrorDetails, } from "./errors.js";
2
+ export { QortexClient, createQortexClient, isQortexHttpError, unwrapSuccessEnvelope, type QortexClientOptions, type QortexJsonResult, type QortexRequestPolicy, } from "./transport.js";
3
+ export { SseDecoder, iterateSse, type QortexSseEvent, } from "./sse.js";
4
+ export { abortableDelay, runWithRecovery, type AttemptOutcome, type QortexAttemptContext, type RecoveryOptions, type RemoteAcceptance, type ReplayAuthorizationContext, } from "./recovery.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,eAAe,EACf,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,GACzB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,UAAU,EACV,UAAU,EACV,KAAK,cAAc,GACpB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,cAAc,EACd,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,0BAA0B,GAChC,MAAM,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { QortexError, QortexHttpError, QortexProtocolError, QortexTimeoutError, QortexTransportError, isAbortError, qortexHttpError, } from "./errors.js";
2
+ export { QortexClient, createQortexClient, isQortexHttpError, unwrapSuccessEnvelope, } from "./transport.js";
3
+ export { SseDecoder, iterateSse, } from "./sse.js";
4
+ export { abortableDelay, runWithRecovery, } from "./recovery.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,eAAe,GAGhB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,GAItB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,UAAU,EACV,UAAU,GAEX,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,cAAc,EACd,eAAe,GAMhB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,35 @@
1
+ export type RemoteAcceptance = "unknown" | "not-accepted" | "accepted";
2
+ export interface AttemptOutcome {
3
+ acceptance: RemoteAcceptance;
4
+ partialOutput: boolean;
5
+ sideEffectStarted: boolean;
6
+ }
7
+ export interface QortexAttemptContext {
8
+ readonly operationId: string;
9
+ readonly attempt: number;
10
+ readonly signal?: AbortSignal;
11
+ markNotAccepted(): void;
12
+ markAccepted(): void;
13
+ markPartialOutput(): void;
14
+ markSideEffectStarted(): void;
15
+ }
16
+ export interface ReplayAuthorizationContext {
17
+ readonly operationId: string;
18
+ readonly attempt: number;
19
+ readonly nextAttempt: number;
20
+ readonly error: unknown;
21
+ readonly outcome: Readonly<AttemptOutcome>;
22
+ readonly signal?: AbortSignal;
23
+ }
24
+ export interface RecoveryOptions<T> {
25
+ operationId: string;
26
+ maxAttempts: number;
27
+ signal?: AbortSignal;
28
+ execute(context: QortexAttemptContext): Promise<T>;
29
+ shouldRetry(error: unknown, context: ReplayAuthorizationContext): boolean;
30
+ authorizeReplay(context: ReplayAuthorizationContext): boolean | Promise<boolean>;
31
+ backoffMs?: number | ((nextAttempt: number, error: unknown) => number);
32
+ }
33
+ export declare function abortableDelay(ms: number, signal?: AbortSignal): Promise<void>;
34
+ export declare function runWithRecovery<T>(options: RecoveryOptions<T>): Promise<T>;
35
+ //# sourceMappingURL=recovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery.d.ts","sourceRoot":"","sources":["../src/recovery.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,cAAc,GAAG,UAAU,CAAC;AAEvE,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,gBAAgB,CAAC;IAC7B,aAAa,EAAE,OAAO,CAAC;IACvB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,eAAe,IAAI,IAAI,CAAC;IACxB,YAAY,IAAI,IAAI,CAAC;IACrB,iBAAiB,IAAI,IAAI,CAAC;IAC1B,qBAAqB,IAAI,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IAC3C,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACnD,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC;IAC1E,eAAe,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACjF,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC,CAAC;CACxE;AAMD,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB9E;AAMD,wBAAsB,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAyEhF"}
@@ -0,0 +1,106 @@
1
+ function abortReason(signal) {
2
+ return signal.reason ?? Object.assign(new Error("The operation was aborted"), { name: "AbortError" });
3
+ }
4
+ export function abortableDelay(ms, signal) {
5
+ if (!Number.isFinite(ms) || ms < 0) {
6
+ return Promise.reject(new RangeError("delay must be a non-negative finite number"));
7
+ }
8
+ if (signal?.aborted)
9
+ return Promise.reject(abortReason(signal));
10
+ if (ms === 0)
11
+ return Promise.resolve();
12
+ return new Promise((resolve, reject) => {
13
+ let settled = false;
14
+ const cleanup = () => {
15
+ clearTimeout(timer);
16
+ signal?.removeEventListener("abort", onAbort);
17
+ };
18
+ const finish = (callback) => {
19
+ if (settled)
20
+ return;
21
+ settled = true;
22
+ cleanup();
23
+ callback();
24
+ };
25
+ const onAbort = () => finish(() => reject(signal ? abortReason(signal) : undefined));
26
+ const timer = setTimeout(() => finish(resolve), ms);
27
+ signal?.addEventListener("abort", onAbort, { once: true });
28
+ if (signal?.aborted)
29
+ onAbort();
30
+ });
31
+ }
32
+ function snapshot(outcome) {
33
+ return Object.freeze({ ...outcome });
34
+ }
35
+ export async function runWithRecovery(options) {
36
+ if (typeof options.operationId !== "string" ||
37
+ !options.operationId.trim() ||
38
+ options.operationId.length > 256) {
39
+ throw new TypeError("operationId must contain between 1 and 256 characters");
40
+ }
41
+ if (!Number.isInteger(options.maxAttempts) || options.maxAttempts < 1 || options.maxAttempts > 5) {
42
+ throw new RangeError("maxAttempts must be an integer between 1 and 5");
43
+ }
44
+ for (let attempt = 1; attempt <= options.maxAttempts; attempt += 1) {
45
+ if (options.signal?.aborted)
46
+ throw abortReason(options.signal);
47
+ const outcome = {
48
+ acceptance: "unknown",
49
+ partialOutput: false,
50
+ sideEffectStarted: false,
51
+ };
52
+ const context = {
53
+ operationId: options.operationId,
54
+ attempt,
55
+ ...(options.signal ? { signal: options.signal } : {}),
56
+ markNotAccepted() {
57
+ if (outcome.acceptance !== "accepted")
58
+ outcome.acceptance = "not-accepted";
59
+ },
60
+ markAccepted() {
61
+ outcome.acceptance = "accepted";
62
+ },
63
+ markPartialOutput() {
64
+ outcome.partialOutput = true;
65
+ },
66
+ markSideEffectStarted() {
67
+ outcome.sideEffectStarted = true;
68
+ },
69
+ };
70
+ try {
71
+ return await options.execute(context);
72
+ }
73
+ catch (error) {
74
+ if (options.signal?.aborted)
75
+ throw abortReason(options.signal);
76
+ if (attempt >= options.maxAttempts)
77
+ throw error;
78
+ const replayContext = Object.freeze({
79
+ operationId: options.operationId,
80
+ attempt,
81
+ nextAttempt: attempt + 1,
82
+ error,
83
+ outcome: snapshot(outcome),
84
+ ...(options.signal ? { signal: options.signal } : {}),
85
+ });
86
+ if (options.shouldRetry(error, replayContext) !== true)
87
+ throw error;
88
+ if (outcome.acceptance === "accepted" ||
89
+ outcome.partialOutput ||
90
+ outcome.sideEffectStarted) {
91
+ throw error;
92
+ }
93
+ if ((await options.authorizeReplay(replayContext)) !== true)
94
+ throw error;
95
+ if (options.signal?.aborted)
96
+ throw abortReason(options.signal);
97
+ const configuredDelay = typeof options.backoffMs === "function"
98
+ ? options.backoffMs(attempt + 1, error)
99
+ : options.backoffMs ?? 0;
100
+ const delay = Math.min(30_000, Math.max(0, configuredDelay));
101
+ await abortableDelay(delay, options.signal);
102
+ }
103
+ }
104
+ throw new Error("Unreachable recovery state");
105
+ }
106
+ //# sourceMappingURL=recovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery.js","sourceRoot":"","sources":["../src/recovery.ts"],"names":[],"mappings":"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"}
package/dist/sse.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ export interface QortexSseEvent {
2
+ data: string;
3
+ event?: string;
4
+ id?: string;
5
+ retry?: number;
6
+ }
7
+ export declare class SseDecoder {
8
+ private readonly decoder;
9
+ private buffer;
10
+ private data;
11
+ private eventName;
12
+ private eventId;
13
+ private lastEventId;
14
+ private retry;
15
+ push(chunk: Uint8Array | string): QortexSseEvent[];
16
+ finish(): QortexSseEvent[];
17
+ private consume;
18
+ private processLine;
19
+ private resetFrame;
20
+ }
21
+ export declare function iterateSse(stream: ReadableStream<Uint8Array>, signal?: AbortSignal): AsyncGenerator<QortexSseEvent>;
22
+ //# sourceMappingURL=sse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../src/sse.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,KAAK,CAAqB;IAElC,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,cAAc,EAAE;IAQlD,MAAM,IAAI,cAAc,EAAE;IAS1B,OAAO,CAAC,OAAO;IAgCf,OAAO,CAAC,WAAW;IA4CnB,OAAO,CAAC,UAAU;CAMnB;AAED,wBAAuB,UAAU,CAC/B,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,MAAM,CAAC,EAAE,WAAW,GACnB,cAAc,CAAC,cAAc,CAAC,CA0ChC"}
package/dist/sse.js ADDED
@@ -0,0 +1,156 @@
1
+ export class SseDecoder {
2
+ decoder = new TextDecoder();
3
+ buffer = "";
4
+ data = [];
5
+ eventName;
6
+ eventId;
7
+ lastEventId;
8
+ retry;
9
+ push(chunk) {
10
+ const text = typeof chunk === "string"
11
+ ? this.decoder.decode() + chunk
12
+ : this.decoder.decode(chunk, { stream: true });
13
+ return this.consume(text, false);
14
+ }
15
+ finish() {
16
+ const tail = this.decoder.decode();
17
+ const events = this.consume(tail, true);
18
+ // A final data line without an empty-line delimiter is an incomplete SSE
19
+ // frame and must not be reported as a completed event.
20
+ this.resetFrame();
21
+ return events;
22
+ }
23
+ consume(text, final) {
24
+ this.buffer += text;
25
+ const events = [];
26
+ let lineStart = 0;
27
+ let cursor = 0;
28
+ while (cursor < this.buffer.length) {
29
+ const char = this.buffer[cursor];
30
+ if (char === "\r") {
31
+ if (cursor + 1 === this.buffer.length && !final)
32
+ break;
33
+ const line = this.buffer.slice(lineStart, cursor);
34
+ if (this.buffer[cursor + 1] === "\n")
35
+ cursor += 1;
36
+ events.push(...this.processLine(line));
37
+ cursor += 1;
38
+ lineStart = cursor;
39
+ }
40
+ else if (char === "\n") {
41
+ events.push(...this.processLine(this.buffer.slice(lineStart, cursor)));
42
+ cursor += 1;
43
+ lineStart = cursor;
44
+ }
45
+ else {
46
+ cursor += 1;
47
+ }
48
+ }
49
+ this.buffer = this.buffer.slice(lineStart);
50
+ if (final && this.buffer.length > 0) {
51
+ events.push(...this.processLine(this.buffer));
52
+ this.buffer = "";
53
+ }
54
+ return events;
55
+ }
56
+ processLine(line) {
57
+ if (line.length === 0) {
58
+ if (this.data.length === 0) {
59
+ this.resetFrame();
60
+ return [];
61
+ }
62
+ const event = {
63
+ data: this.data.join("\n"),
64
+ ...(this.eventName ? { event: this.eventName } : {}),
65
+ ...(this.eventId ?? this.lastEventId
66
+ ? { id: this.eventId ?? this.lastEventId }
67
+ : {}),
68
+ ...(this.retry === undefined ? {} : { retry: this.retry }),
69
+ };
70
+ this.resetFrame();
71
+ return [event];
72
+ }
73
+ if (line.startsWith(":"))
74
+ return [];
75
+ const separator = line.indexOf(":");
76
+ const field = separator === -1 ? line : line.slice(0, separator);
77
+ let value = separator === -1 ? "" : line.slice(separator + 1);
78
+ if (value.startsWith(" "))
79
+ value = value.slice(1);
80
+ switch (field) {
81
+ case "data":
82
+ this.data.push(value);
83
+ break;
84
+ case "event":
85
+ this.eventName = value;
86
+ break;
87
+ case "id":
88
+ if (!value.includes("\0")) {
89
+ this.eventId = value;
90
+ this.lastEventId = value;
91
+ }
92
+ break;
93
+ case "retry":
94
+ if (/^\d+$/.test(value))
95
+ this.retry = Number(value);
96
+ break;
97
+ }
98
+ return [];
99
+ }
100
+ resetFrame() {
101
+ this.data = [];
102
+ this.eventName = undefined;
103
+ this.eventId = undefined;
104
+ this.retry = undefined;
105
+ }
106
+ }
107
+ export async function* iterateSse(stream, signal) {
108
+ const reader = stream.getReader();
109
+ const decoder = new SseDecoder();
110
+ let abortListener;
111
+ let ended = false;
112
+ try {
113
+ if (signal?.aborted) {
114
+ throw signal.reason ?? Object.assign(new Error("The stream was aborted"), { name: "AbortError" });
115
+ }
116
+ if (signal) {
117
+ abortListener = () => {
118
+ void reader.cancel(signal.reason).catch(() => { });
119
+ };
120
+ signal.addEventListener("abort", abortListener, { once: true });
121
+ }
122
+ while (true) {
123
+ const next = await reader.read();
124
+ if (signal?.aborted) {
125
+ throw signal.reason ?? Object.assign(new Error("The stream was aborted"), { name: "AbortError" });
126
+ }
127
+ if (next.done) {
128
+ ended = true;
129
+ break;
130
+ }
131
+ for (const event of decoder.push(next.value))
132
+ yield event;
133
+ }
134
+ for (const event of decoder.finish())
135
+ yield event;
136
+ }
137
+ finally {
138
+ if (signal && abortListener)
139
+ signal.removeEventListener("abort", abortListener);
140
+ if (!ended) {
141
+ try {
142
+ await reader.cancel(signal?.reason);
143
+ }
144
+ catch {
145
+ // Preserve the original abort or consumer error.
146
+ }
147
+ }
148
+ try {
149
+ reader.releaseLock();
150
+ }
151
+ catch {
152
+ // The stream may still be resolving a cancelled read.
153
+ }
154
+ }
155
+ }
156
+ //# sourceMappingURL=sse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.js","sourceRoot":"","sources":["../src/sse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { QortexHttpError } from "./errors.js";
2
+ export interface QortexClientOptions {
3
+ baseUrl: string | URL;
4
+ fetch?: typeof globalThis.fetch;
5
+ defaultHeaders?: HeadersInit;
6
+ timeoutMs?: number;
7
+ }
8
+ export interface QortexRequestPolicy {
9
+ signal?: AbortSignal;
10
+ timeoutMs?: number;
11
+ }
12
+ export interface QortexJsonResult<T> {
13
+ data: T;
14
+ status: number;
15
+ headers: Headers;
16
+ requestId?: string;
17
+ }
18
+ export declare class QortexClient {
19
+ private readonly baseUrl;
20
+ private readonly fetchImpl;
21
+ private readonly defaultHeaders?;
22
+ private readonly defaultTimeoutMs?;
23
+ constructor(options: QortexClientOptions);
24
+ request(target: RequestInfo | URL, init?: RequestInit, policy?: QortexRequestPolicy): Promise<Response>;
25
+ requestJson<T = unknown>(target: RequestInfo | URL, init?: RequestInit, policy?: QortexRequestPolicy): Promise<QortexJsonResult<T>>;
26
+ getRequestStatus<T = unknown>(requestId: string, policy?: QortexRequestPolicy & {
27
+ headers?: HeadersInit;
28
+ }): Promise<QortexJsonResult<T>>;
29
+ openStream(target: RequestInfo | URL, init?: RequestInit, policy?: QortexRequestPolicy): Promise<Response>;
30
+ }
31
+ export declare function createQortexClient(options: QortexClientOptions): QortexClient;
32
+ export declare function unwrapSuccessEnvelope(value: unknown): unknown;
33
+ export declare function isQortexHttpError(error: unknown): error is QortexHttpError;
34
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EAKhB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,IAAI,EAAE,CAAC,CAAC;IACR,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAqJD,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAM;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IACpD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAc;IAC9C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAS;gBAE/B,OAAO,EAAE,mBAAmB;IAgBlC,OAAO,CACX,MAAM,EAAE,WAAW,GAAG,GAAG,EACzB,IAAI,GAAE,WAAgB,EACtB,MAAM,GAAE,mBAAwB,GAC/B,OAAO,CAAC,QAAQ,CAAC;IA+Cd,WAAW,CAAC,CAAC,GAAG,OAAO,EAC3B,MAAM,EAAE,WAAW,GAAG,GAAG,EACzB,IAAI,GAAE,WAAgB,EACtB,MAAM,GAAE,mBAAwB,GAC/B,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAwBzB,gBAAgB,CAAC,CAAC,GAAG,OAAO,EAChC,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,mBAAmB,GAAG;QAAE,OAAO,CAAC,EAAE,WAAW,CAAA;KAAO,GAC3D,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAS/B,UAAU,CACR,MAAM,EAAE,WAAW,GAAG,GAAG,EACzB,IAAI,GAAE,WAAgB,EACtB,MAAM,GAAE,mBAAwB,GAC/B,OAAO,CAAC,QAAQ,CAAC;CAGrB;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,YAAY,CAE7E;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAW7D;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAE1E"}
@@ -0,0 +1,232 @@
1
+ import { QortexHttpError, QortexProtocolError, QortexTimeoutError, QortexTransportError, qortexHttpError, } from "./errors.js";
2
+ function makeAbortScope(signals, timeoutMs) {
3
+ if (timeoutMs !== undefined && (!Number.isFinite(timeoutMs) || timeoutMs <= 0)) {
4
+ throw new RangeError("timeoutMs must be a positive finite number");
5
+ }
6
+ const controller = new AbortController();
7
+ const removers = [];
8
+ let expired = false;
9
+ let timer;
10
+ for (const signal of new Set(signals.filter((item) => Boolean(item)))) {
11
+ if (signal.aborted) {
12
+ controller.abort(signal.reason);
13
+ continue;
14
+ }
15
+ const onAbort = () => controller.abort(signal.reason);
16
+ signal.addEventListener("abort", onAbort, { once: true });
17
+ removers.push(() => signal.removeEventListener("abort", onAbort));
18
+ }
19
+ if (timeoutMs !== undefined && !controller.signal.aborted) {
20
+ timer = setTimeout(() => {
21
+ expired = true;
22
+ const timeout = new Error("Qortex request timed out");
23
+ timeout.name = "TimeoutError";
24
+ controller.abort(timeout);
25
+ }, timeoutMs);
26
+ }
27
+ return {
28
+ signal: controller.signal,
29
+ timedOut: () => expired,
30
+ timeoutError: (cause) => new QortexTimeoutError(timeoutMs ?? 0, { cause }),
31
+ dispose() {
32
+ if (timer !== undefined)
33
+ clearTimeout(timer);
34
+ for (const remove of removers)
35
+ remove();
36
+ },
37
+ };
38
+ }
39
+ function resolveTarget(target, baseUrl) {
40
+ if (target instanceof Request)
41
+ return target;
42
+ return new URL(target.toString(), baseUrl);
43
+ }
44
+ function targetUrl(target) {
45
+ return new URL(target instanceof Request ? target.url : target.toString());
46
+ }
47
+ function mergeHeaders(defaults, requestHeaders, initHeaders) {
48
+ const merged = new Headers(defaults);
49
+ for (const source of [requestHeaders, initHeaders]) {
50
+ new Headers(source).forEach((value, key) => merged.set(key, value));
51
+ }
52
+ return merged;
53
+ }
54
+ function getRequestId(headers) {
55
+ const value = headers.get("x-request-id") ??
56
+ headers.get("request-id") ??
57
+ headers.get("x-qlex-request-id");
58
+ return value && /^[A-Za-z0-9_.:-]{1,160}$/.test(value) ? value : undefined;
59
+ }
60
+ function withBodyLifecycle(response, scope) {
61
+ if (!response.body) {
62
+ scope.dispose();
63
+ return response;
64
+ }
65
+ const reader = response.body.getReader();
66
+ let finished = false;
67
+ const finish = () => {
68
+ if (finished)
69
+ return;
70
+ finished = true;
71
+ scope.dispose();
72
+ try {
73
+ reader.releaseLock();
74
+ }
75
+ catch {
76
+ // A pending read owns the lock until its promise settles.
77
+ }
78
+ };
79
+ const body = new ReadableStream({
80
+ async pull(controller) {
81
+ try {
82
+ const next = await reader.read();
83
+ if (next.done) {
84
+ finish();
85
+ controller.close();
86
+ return;
87
+ }
88
+ controller.enqueue(next.value);
89
+ }
90
+ catch (error) {
91
+ finish();
92
+ controller.error(scope.timedOut() ? scope.timeoutError(error) : error);
93
+ }
94
+ },
95
+ async cancel(reason) {
96
+ try {
97
+ await reader.cancel(reason);
98
+ }
99
+ finally {
100
+ finish();
101
+ }
102
+ },
103
+ });
104
+ return new Response(body, {
105
+ status: response.status,
106
+ statusText: response.statusText,
107
+ headers: response.headers,
108
+ });
109
+ }
110
+ function parseResponseBody(text) {
111
+ if (text.length === 0)
112
+ return undefined;
113
+ try {
114
+ return JSON.parse(text);
115
+ }
116
+ catch {
117
+ return text;
118
+ }
119
+ }
120
+ function isErrorEnvelope(value) {
121
+ return (value !== null &&
122
+ typeof value === "object" &&
123
+ !Array.isArray(value) &&
124
+ value.success === false);
125
+ }
126
+ export class QortexClient {
127
+ baseUrl;
128
+ fetchImpl;
129
+ defaultHeaders;
130
+ defaultTimeoutMs;
131
+ constructor(options) {
132
+ this.baseUrl = new URL(options.baseUrl);
133
+ const host = this.baseUrl.hostname.replace(/^\[|\]$/g, "");
134
+ const loopback = host === "localhost" || host === "127.0.0.1" || host === "::1";
135
+ if (this.baseUrl.protocol !== "https:" && !loopback) {
136
+ throw new TypeError("Qortex baseUrl must use HTTPS outside localhost");
137
+ }
138
+ if (!this.baseUrl.pathname.endsWith("/"))
139
+ this.baseUrl.pathname += "/";
140
+ this.fetchImpl = options.fetch ?? globalThis.fetch;
141
+ if (typeof this.fetchImpl !== "function") {
142
+ throw new TypeError("A fetch implementation is required");
143
+ }
144
+ this.defaultHeaders = options.defaultHeaders;
145
+ this.defaultTimeoutMs = options.timeoutMs;
146
+ }
147
+ async request(target, init = {}, policy = {}) {
148
+ const resolved = resolveTarget(target, this.baseUrl);
149
+ if (targetUrl(resolved).origin !== this.baseUrl.origin) {
150
+ throw new TypeError("Qortex requests must stay on the configured base URL origin");
151
+ }
152
+ const requestSignal = target instanceof Request ? target.signal : undefined;
153
+ const scope = makeAbortScope([requestSignal, init.signal, policy.signal], policy.timeoutMs ?? this.defaultTimeoutMs);
154
+ const headers = mergeHeaders(this.defaultHeaders, requestSignal ? target.headers : undefined, init.headers);
155
+ try {
156
+ if (scope.signal.aborted) {
157
+ if (scope.timedOut()) {
158
+ throw scope.timeoutError();
159
+ }
160
+ throw scope.signal.reason ?? Object.assign(new Error("The request was aborted"), { name: "AbortError" });
161
+ }
162
+ const response = await this.fetchImpl(resolved, {
163
+ ...init,
164
+ headers,
165
+ signal: scope.signal,
166
+ });
167
+ if (scope.signal.aborted) {
168
+ if (scope.timedOut()) {
169
+ throw scope.timeoutError();
170
+ }
171
+ throw scope.signal.reason ?? Object.assign(new Error("The request was aborted"), { name: "AbortError" });
172
+ }
173
+ return withBodyLifecycle(response, scope);
174
+ }
175
+ catch (error) {
176
+ scope.dispose();
177
+ if (scope.timedOut()) {
178
+ throw new QortexTimeoutError(policy.timeoutMs ?? this.defaultTimeoutMs ?? 0, {
179
+ cause: error,
180
+ });
181
+ }
182
+ if (scope.signal.aborted)
183
+ throw error;
184
+ throw new QortexTransportError({ cause: error });
185
+ }
186
+ }
187
+ async requestJson(target, init = {}, policy = {}) {
188
+ const response = await this.request(target, init, policy);
189
+ const text = await response.text();
190
+ const data = parseResponseBody(text);
191
+ if (!response.ok || isErrorEnvelope(data)) {
192
+ throw qortexHttpError(response.status, data, response.headers);
193
+ }
194
+ if (text.length > 0 && typeof data === "string" && response.ok) {
195
+ throw new QortexProtocolError("Qortex returned a non-JSON response where JSON was expected", response.status, getRequestId(response.headers));
196
+ }
197
+ return {
198
+ data: data,
199
+ status: response.status,
200
+ headers: new Headers(response.headers),
201
+ ...(getRequestId(response.headers)
202
+ ? { requestId: getRequestId(response.headers) }
203
+ : {}),
204
+ };
205
+ }
206
+ async getRequestStatus(requestId, policy = {}) {
207
+ if (!requestId.trim())
208
+ throw new TypeError("requestId must not be empty");
209
+ const url = new URL(`/auth/usage/v1/requests/${encodeURIComponent(requestId)}`, this.baseUrl.origin);
210
+ return this.requestJson(url, { method: "GET", headers: policy.headers }, policy);
211
+ }
212
+ openStream(target, init = {}, policy = {}) {
213
+ return this.request(target, init, policy);
214
+ }
215
+ }
216
+ export function createQortexClient(options) {
217
+ return new QortexClient(options);
218
+ }
219
+ export function unwrapSuccessEnvelope(value) {
220
+ if (value !== null &&
221
+ typeof value === "object" &&
222
+ !Array.isArray(value) &&
223
+ value.success === true &&
224
+ Object.hasOwn(value, "data")) {
225
+ return value.data;
226
+ }
227
+ return value;
228
+ }
229
+ export function isQortexHttpError(error) {
230
+ return error instanceof QortexHttpError;
231
+ }
232
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,30 @@
1
1
  {
2
2
  "name": "@qitqode/qitqore",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "Shared, host-neutral Qortex HTTP, streaming, and recovery primitives",
5
+ "type": "module",
6
+ "engines": {
7
+ "node": ">=24"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist/**",
19
+ "README.md"
20
+ ],
21
+ "sideEffects": false,
22
+ "scripts": {
23
+ "build": "tsc -p tsconfig.json",
24
+ "test": "npm run build && node --test test/*.test.mjs",
25
+ "prepack": "npm test"
26
+ },
27
+ "devDependencies": {
28
+ "typescript": "^5.9.3"
29
+ }
30
+ }