diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 97bce11..4e31c15 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.23.0" + ".": "0.23.1" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cd5fac..682f1a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## 0.23.1 (2026-02-05) + +Full Changelog: [v0.23.0...v0.23.1](https://github.com/perplexityai/perplexity-node/compare/v0.23.0...v0.23.1) + +### Bug Fixes + +* **client:** avoid memory leak with abort signals ([ec22b56](https://github.com/perplexityai/perplexity-node/commit/ec22b560c4a668a49dc5c8e2bf0fa69a155ccb93)) +* **client:** avoid removing abort listener too early ([12e45f7](https://github.com/perplexityai/perplexity-node/commit/12e45f70f41991f4c0385886a9dc407173c8bc7c)) + + +### Chores + +* **client:** do not parse responses with empty content-length ([31c81b4](https://github.com/perplexityai/perplexity-node/commit/31c81b49e1bad9d4e287eeb455b202398f4ec8ef)) +* **client:** restructure abort controller binding ([c93217d](https://github.com/perplexityai/perplexity-node/commit/c93217db4a28bea06115b20cd21557fdf989ddd1)) + ## 0.23.0 (2026-01-27) Full Changelog: [v0.22.0...v0.23.0](https://github.com/perplexityai/perplexity-node/compare/v0.22.0...v0.23.0) diff --git a/package.json b/package.json index 814f0fd..f515c5a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@perplexity-ai/perplexity_ai", - "version": "0.23.0", + "version": "0.23.1", "description": "The official TypeScript library for the Perplexity API", "author": "Perplexity ", "types": "dist/index.d.ts", diff --git a/src/client.ts b/src/client.ts index 11dd6e3..f2a53fa 100644 --- a/src/client.ts +++ b/src/client.ts @@ -508,9 +508,10 @@ export class Perplexity { controller: AbortController, ): Promise { const { signal, method, ...options } = init || {}; - if (signal) signal.addEventListener('abort', () => controller.abort()); + const abort = this._makeAbort(controller); + if (signal) signal.addEventListener('abort', abort, { once: true }); - const timeout = setTimeout(() => controller.abort(), ms); + const timeout = setTimeout(abort, ms); const isReadableBody = ((globalThis as any).ReadableStream && options.body instanceof (globalThis as any).ReadableStream) || @@ -677,6 +678,12 @@ export class Perplexity { return headers.values; } + private _makeAbort(controller: AbortController) { + // note: we can't just inline this method inside `fetchWithTimeout()` because then the closure + // would capture all request options, and cause a memory leak. + return () => controller.abort(); + } + private buildBody({ options: { body, headers: rawHeaders } }: { options: FinalRequestOptions }): { bodyHeaders: HeadersLike; body: BodyInit | undefined; diff --git a/src/internal/parse.ts b/src/internal/parse.ts index a9270fb..323a055 100644 --- a/src/internal/parse.ts +++ b/src/internal/parse.ts @@ -43,6 +43,12 @@ export async function defaultParseResponse(client: Perplexity, props: APIResp const mediaType = contentType?.split(';')[0]?.trim(); const isJSON = mediaType?.includes('application/json') || mediaType?.endsWith('+json'); if (isJSON) { + const contentLength = response.headers.get('content-length'); + if (contentLength === '0') { + // if there is no content we can't do anything + return undefined as T; + } + const json = await response.json(); return json as T; } diff --git a/src/version.ts b/src/version.ts index d77fad4..40afe2f 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '0.23.0'; // x-release-please-version +export const VERSION = '0.23.1'; // x-release-please-version