Skip to content

Separate React and Core SDK#126

Merged
arjunkomath merged 2 commits intodevelopfrom
feat/react-core-sdk
Dec 20, 2025
Merged

Separate React and Core SDK#126
arjunkomath merged 2 commits intodevelopfrom
feat/react-core-sdk

Conversation

@arjunkomath
Copy link
Copy Markdown
Member

@arjunkomath arjunkomath commented Dec 20, 2025

Summary by CodeRabbit

  • New Features

    • Added a standalone core SDK with new client APIs (including getPinnedPost) and tag-label utility.
  • Bug Fixes

    • ChangelogPost render props now expose publicationDate and conditionally render dates to avoid incorrect/null date display.
  • Chores

    • Split SDK into modular packages and updated package dependencies.
  • Documentation

    • Added/updated READMEs describing SDK usage, APIs, and types.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link
Copy Markdown

vercel bot commented Dec 20, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
changes-page Ready Ready Preview Dec 20, 2025 6:14am
2 Skipped Deployments
Project Deployment Review Updated (UTC)
changes-page-docs Skipped Skipped Dec 20, 2025 6:14am
user-changes-page Skipped Skipped Dec 20, 2025 6:14am

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Dec 20, 2025

Walkthrough

Adds a new framework-agnostic package @changespage/core (types, client factory, tag util) and a getPinnedPost() client method; migrates types and utilities in packages/react-sdk to depend on and re-export from the core package and updates ChangelogPost props to use publicationDate.

Changes

Cohort / File(s) Summary
Core package manifest & build
packages/core-sdk/package.json, packages/core-sdk/tsconfig.json, packages/core-sdk/README.md
New @changespage/core package with build/publish scripts, TS config, and README/documentation.
Core public types
packages/core-sdk/src/types.ts
Adds exported types and interfaces: PostTag, Post, ClientConfig, GetPostsOptions, GetPostsResult, and ChangesPageClient (includes getPinnedPost).
Core client implementation
packages/core-sdk/src/client.ts, packages/core-sdk/src/index.ts
Implements createChangesPageClient and adds getPinnedPost(); barrel exports client, types, and utilities (e.g., getTagLabel).
Core utilities
packages/core-sdk/src/utils.ts
Adds getTagLabel(tag: PostTag): string and tagLabels mapping.
React SDK dependency update
packages/react-sdk/package.json
Adds workspace dependency: @changespage/core: "workspace:*".
React SDK exports & types migration
packages/react-sdk/src/index.ts, packages/react-sdk/src/types.ts
Re-exports core types/utilities from @changespage/core; moves ChangelogPostProps/ChangelogPostRenderProps exports to local ./types; date renamed to publicationDate (string
React SDK components / hooks updates
packages/react-sdk/src/components/ChangelogPost.tsx, packages/react-sdk/src/hooks/usePosts.ts
ChangelogPost signature removes locale and exposes publicationDate; usePosts now imports types from @changespage/core.
App usage
apps/web/pages/changelog.tsx
Uses publicationDate for conditional/localized rendering of post date.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review packages/core-sdk/src/types.ts for accurate type shapes and nullable date semantics.
  • Inspect getPinnedPost() in packages/core-sdk/src/client.ts for correct HTTP handling (404 → null, other errors thrown) and header usage.
  • Verify packages/react-sdk/src/index.ts re-exports are consistent and do not create circular exports.
  • Confirm ChangelogPost render-prop contract (publicationDate type) matches component usage in apps/web.
  • Check package.json publishConfig and workspace dependency resolution for @changespage/core.

Poem

🐇 I hopped a path of files and types tonight,
I packed a core with tags and posts just right,
React now borrows, tidy and bright,
Pinned posts peek out, a lovely sight,
Hooray — a small hop, and the package takes flight! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Separate React and Core SDK' accurately reflects the main objective of the pull request, which creates a new core SDK package and reorganizes the React SDK to depend on it.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/react-core-sdk

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/react-sdk/src/types.ts (1)

25-25: Consider using a regular import for consistency.

The inline import syntax works but is less conventional. For better readability and consistency with the rest of the file, consider importing Post at the top.

🔎 Proposed refactor
 import type { ReactNode } from "react";
-import type { PostTag } from "@changespage/core";
+import type { Post, PostTag } from "@changespage/core";

Then update line 25:

 export interface ChangelogPostProps {
-  post: import("@changespage/core").Post;
+  post: Post;
   locale?: string;
   children: (props: ChangelogPostRenderProps) => ReactNode;
 }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a2326b6 and 29a017e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (11)
  • packages/core-sdk/package.json (1 hunks)
  • packages/core-sdk/src/client.ts (1 hunks)
  • packages/core-sdk/src/index.ts (1 hunks)
  • packages/core-sdk/src/types.ts (1 hunks)
  • packages/core-sdk/src/utils.ts (2 hunks)
  • packages/core-sdk/tsconfig.json (1 hunks)
  • packages/react-sdk/package.json (1 hunks)
  • packages/react-sdk/src/components/ChangelogPost.tsx (1 hunks)
  • packages/react-sdk/src/hooks/usePosts.ts (1 hunks)
  • packages/react-sdk/src/index.ts (1 hunks)
  • packages/react-sdk/src/types.ts (2 hunks)
🔇 Additional comments (12)
packages/core-sdk/tsconfig.json (1)

1-21: LGTM! Well-configured TypeScript setup for a library package.

The configuration is appropriate for a modern TypeScript library with proper declaration file generation, strict mode, and ESNext module support. The moduleResolution: "bundler" option is compatible with TypeScript 5.3.3 specified in the package.json.

packages/core-sdk/src/utils.ts (2)

19-22: LGTM! Robust validation for date formatting.

The added validation checks properly handle edge cases:

  • Null, empty, or whitespace-only strings
  • Invalid date strings that cannot be parsed

Returning an empty string for invalid dates is a sensible default for UI display.


31-36: LGTM! Consistent validation pattern.

The validation logic matches the approach in formatDate, ensuring that only valid Date objects are returned. Returning null for invalid dates is appropriate for the API contract.

packages/react-sdk/package.json (1)

20-22: LGTM! Correct monorepo dependency setup.

The workspace dependency on @changespage/core is properly configured using the workspace:* protocol, which is the standard approach for monorepo package dependencies.

packages/core-sdk/package.json (1)

1-34: LGTM! Standard package configuration for a TypeScript library.

The package manifest is properly configured with:

  • ESM module type and exports
  • TypeScript build pipeline using tsc
  • Public access for npm publishing
  • Appropriate metadata and repository info
packages/core-sdk/src/types.ts (1)

1-34: LGTM! Comprehensive and well-structured type definitions.

The type definitions provide a solid foundation for the core SDK:

  • Clear PostTag union type
  • Complete Post interface with all necessary fields
  • Simple, focused interfaces for configuration and options
  • Well-defined client interface including the new getPinnedPost method
packages/react-sdk/src/hooks/usePosts.ts (1)

4-4: LGTM! Clean migration to core types.

The import has been correctly updated to use types from the new @changespage/core package, aligning with the PR's objective to centralize shared types.

packages/react-sdk/src/components/ChangelogPost.tsx (1)

1-1: LGTM! Clean migration to core utilities.

The date utility imports have been correctly updated to use the centralized implementations from @changespage/core.

packages/core-sdk/src/client.ts (1)

76-80: LGTM! Method properly exposed in client interface.

The getPinnedPost method is correctly added to the returned client object, matching the ChangesPageClient interface definition in types.ts.

packages/core-sdk/src/index.ts (1)

1-10: LGTM! Clean barrel export structure.

The core SDK public API is well-organized with clear separation between client creation, utilities, and type exports. This establishes a solid foundation for the new @changespage/core package.

packages/react-sdk/src/types.ts (1)

4-11: LGTM! Proper type re-exports from core package.

The type exports correctly delegate to @changespage/core, maintaining backward compatibility while centralizing type definitions.

packages/react-sdk/src/index.ts (1)

1-23: LGTM! Excellent refactoring to delegate to core package.

The React SDK now properly re-exports core functionality from @changespage/core while maintaining its own React-specific exports (components and hooks). This achieves the PR objective of separating core and React SDK functionality while maintaining backward compatibility.

@vercel vercel bot temporarily deployed to Preview – user-changes-page December 20, 2025 06:07 Inactive
@vercel vercel bot temporarily deployed to Preview – changes-page-docs December 20, 2025 06:07 Inactive
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/react-sdk/README.md (2)

60-62: Document the new getPinnedPost() method.

The PR introduces a getPinnedPost() client method per the AI summary, but it's not documented in the README. Add documentation for this new public API method alongside the existing getLatestPost() method to maintain API completeness.

🔎 Suggested addition to document getPinnedPost()
 ### `client.getLatestPost()`
 
 Returns the most recent post or `null`.
+
+### `client.getPinnedPost()`
+
+Returns the pinned post or `null`.

64-68: Document migration path for breaking changes in <ChangelogPost> render props.

The render prop interface has changed—publicationDate replaces the previous date properties, and per the enriched context, locale has been removed from props. These are breaking changes that should be clearly documented to help users migrate from older versions.

Consider adding a brief migration section or inline note highlighting what changed to enable users to update their code.

🧹 Nitpick comments (2)
apps/web/pages/changelog.tsx (1)

52-60: Consider defensive error handling for invalid dates.

The conditional rendering checks for the existence of publicationDate, but if the value is an invalid date string, new Date(publicationDate).toLocaleDateString() may throw an error or return "Invalid Date".

🔎 Suggested defensive date handling
-                  {publicationDate && (
+                  {publicationDate && !isNaN(new Date(publicationDate).getTime()) && (
                     <time className="text-sm text-gray-500 dark:text-gray-400">
                       {new Date(publicationDate).toLocaleDateString("en-US", {
                         year: "numeric",
                         month: "long",
                         day: "numeric",
                       })}
                     </time>
                   )}

Alternatively, you could wrap the date parsing in a try-catch or create a helper function for safer date formatting.

packages/core-sdk/README.md (1)

42-50: Consider varying sentence structure for better readability.

Three consecutive API descriptions begin with "Returns," which creates repetitive phrasing. Consider varying the sentence structure for improved documentation flow.

📝 Suggested rewording
-Returns `{ posts, totalCount, hasMore }`
+Retrieves a paginated list of posts, returning `{ posts, totalCount, hasMore }`.

 ### `client.getLatestPost()`

-Returns the most recent post or `null`.
+Fetches the most recent post, or `null` if none exists.

 ### `client.getPinnedPost()`

-Returns the pinned post or `null` if none is pinned.
+Retrieves the currently pinned post, or `null` if no post is pinned.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 29a017e and 37ae90b.

📒 Files selected for processing (8)
  • apps/web/pages/changelog.tsx (1 hunks)
  • packages/core-sdk/README.md (1 hunks)
  • packages/core-sdk/src/index.ts (1 hunks)
  • packages/core-sdk/src/utils.ts (1 hunks)
  • packages/react-sdk/README.md (2 hunks)
  • packages/react-sdk/src/components/ChangelogPost.tsx (1 hunks)
  • packages/react-sdk/src/index.ts (1 hunks)
  • packages/react-sdk/src/types.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/core-sdk/src/index.ts
  • packages/react-sdk/src/types.ts
  • packages/react-sdk/src/components/ChangelogPost.tsx
🧰 Additional context used
🪛 LanguageTool
packages/core-sdk/README.md

[style] ~49-~49: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... null. ### client.getPinnedPost() Returns the pinned post or null if none is pi...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🔇 Additional comments (3)
packages/react-sdk/README.md (1)

28-28: API documentation correctly reflects publicationDate property.

The changes to the usage example and render prop documentation properly document the shift to publicationDate, aligning with the core SDK migration. The implementation example demonstrates correct date handling with new Date(publicationDate).toLocaleDateString().

Also applies to: 31-31, 68-68

packages/react-sdk/src/index.ts (1)

1-18: The refactoring to re-export from @changespage/core is complete and correct. All items from core that are re-exported match exactly with what the core package exports (createChangesPageClient, getTagLabel, and their associated types). No breaking changes were introduced.

The original claim about formatDate and parseDate utilities being removed is incorrect—these utilities do not exist in the codebase and were never exported, so there is no breaking change to document.

Likely an incorrect or invalid review comment.

packages/core-sdk/src/utils.ts (1)

1-13: LGTM! Clean utility implementation.

The getTagLabel function is well-implemented with proper type safety and a sensible fallback using nullish coalescing. All PostTag values (fix, new, improvement, announcement, alert) are covered in the tagLabels mapping, enforced by the Record<PostTag, string> type annotation.

@arjunkomath arjunkomath merged commit e838ebc into develop Dec 20, 2025
7 checks passed
@arjunkomath arjunkomath deleted the feat/react-core-sdk branch December 20, 2025 06:17
@coderabbitai coderabbitai bot mentioned this pull request Dec 21, 2025
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