Skip to content

chore: harden existing platform implementation#1402

Closed
joker23 wants to merge 7 commits into
mainfrom
skz/sdk-2195/node-client-sdk-next-port-client
Closed

chore: harden existing platform implementation#1402
joker23 wants to merge 7 commits into
mainfrom
skz/sdk-2195/node-client-sdk-next-port-client

Conversation

@joker23
Copy link
Copy Markdown
Contributor

@joker23 joker23 commented Jun 1, 2026

This PR hardens the node client sdk platform implementation that is already merged. This is done in response to some reviews ran on a future branch.

What changed:

  • NodeStorage: log (no longer swallow) flush errors; validate/log on malformed cache reads and ignore non-string cache values; writethe temp file via an exclusive wx open so the write cannot be redirected through a symlink; warn when getNodeStorage is called with a localStoragePath that differs from the process singleton's.
  • NodeResponse: cap the buffered response body (100 MB) to prevent memory exhaustion from an oversized or hostile response.
  • NodeRequests: apply a default 30s request timeout when a caller does not supply one, so a stuck server cannot hang polling or event delivery.

Note

Medium Risk
Large new client lifecycle (identify, connection modes, events) plus filesystem and HTTP behavior changes; mistakes could affect flag delivery, caching, or resource use, though changes are heavily tested.

Overview
This PR delivers the LaunchDarkly Node client-side SDK (createClient, start/identify, variations, events, connection modes) on top of shared js-client-sdk-common, with NodeDataManager handling bootstrap vs cache, streaming/polling/offline, and fixes for bootstrap+streaming (no duplicate identify callbacks), post-close identify, and offline mid-identify.

Platform hardening (aligned with the stated goal): NodeStorage logs malformed cache and flush failures, keeps only string cache entries, writes via exclusive wx temp files (symlink-safe), and warns when a second localStoragePath is ignored; NodeResponse rejects bodies over 100 MB; NodeRequests applies a 30s default HTTP timeout.

Broad Jest coverage was added for bootstrap, data sources, events, and the public client API; release tooling drops src/index.ts from node-client release-please extra-files.

Reviewed by Cursor Bugbot for commit ec40d10. Bugbot is set up for automated code reviews on this repo. Configure here.

joker23 and others added 7 commits May 29, 2026 12:17
Pins the new hardening behavior:
- NodeStorage: warn on malformed cache, non-string cache values ignored,
  symlink-safe temp write, localStoragePath-mismatch warning.
- NodeResponse: rejects when the body exceeds the size cap (exports
  MAX_RESPONSE_BYTES so the test references the exact threshold).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

@launchdarkly/js-sdk-common size report
This is the brotli compressed size of the ESM build.
Compressed size: 26389 bytes
Compressed size limit: 29000
Uncompressed size: 129320 bytes

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

@launchdarkly/js-client-sdk-common size report
This is the brotli compressed size of the ESM build.
Compressed size: 38516 bytes
Compressed size limit: 39000
Uncompressed size: 211129 bytes

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

@launchdarkly/js-client-sdk size report
This is the brotli compressed size of the ESM build.
Compressed size: 31922 bytes
Compressed size limit: 34000
Uncompressed size: 113733 bytes

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

@launchdarkly/browser size report
This is the brotli compressed size of the ESM build.
Compressed size: 179400 bytes
Compressed size limit: 200000
Uncompressed size: 830912 bytes

@joker23
Copy link
Copy Markdown
Contributor Author

joker23 commented Jun 1, 2026

@cursor review

@joker23 joker23 closed this Jun 1, 2026
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ec40d10. Configure here.

} catch (error) {
this._logger?.warn(
`Discarding malformed flag cache at ${this._storageFile}: ${error instanceof Error ? error.message : error}`,
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spurious warning on first run when no cache exists

Medium Severity

The inner catch block in _initialize now logs a "Discarding malformed flag cache" warning for every error from fs.readFile, including ENOENT when the cache file simply doesn't exist yet. On first SDK use (or after cache cleanup), every user with a logger will see this misleading warning even though there's nothing wrong — the file just hasn't been created. The warning text should only appear for genuinely malformed content, not a missing file.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit ec40d10. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant