Skip to content

Replace lifetime pull-count ranking with precomputed download-rate data - #60

Merged
daneshk merged 9 commits into
wso2:mainfrom
Akil-Dikshan:feat/ranking-download-rate
Oct 2, 2026
Merged

daneshk merged 9 commits into
wso2:mainfrom
Akil-Dikshan:feat/ranking-download-rate

Conversation

@Akil-Dikshan

Copy link
Copy Markdown
Contributor

Description

Replaces "Most Popular" sorting (previously raw lifetime pullCount) with a download-rate metric computed from each connector's latest mature version. This is build-time/scheduled, not live — no new backend, no runtime calls to Central from the Store itself.

A version is mature once it is at least 15 days old. An immature version falls back to the most recent mature version's rate; a package with no mature version ever gets a null rate and sorts to the bottom.

Type of Change

  • New feature (non-breaking change which adds functionality)
  • Performance improvement
  • Test addition/update

Related Issue(s)

Relates to the connector ranking/prioritization discussion with the team.

Changes Made

  • Fixes a pre-existing, unrelated duplicate-fetch bug: HomePage fired fetchPageData twice on every initial page load
  • Adds scripts/generate-ranking-data.js — fetches from Central, computes each package's download rate from its latest mature version
  • Adds .github/workflows/update-ranking-data.yml — runs the generator monthly (or on manual dispatch), opens a PR only when the data changes
  • Wires "Most Popular" in rest-client.ts to read from the precomputed data, log-transformed before comparing (the real spread across the catalog is several orders of magnitude)

Testing Performed

Test Environment

  • Browser(s): Chrome
  • OS: Linux
  • Node Version: 18.x (repo's pinned version; verified against Node 24 locally as well)

Test Cases

  • Unit tests pass (npm test) — 101/101, 6 suites
  • Integration tests pass (if applicable)
  • Manual testing completed
  • Tested on mobile devices
  • Tested on desktop browsers

Also dry-run tested the scheduled workflow end-to-end on a personal fork: confirmed it correctly opens a PR when the generated data changes, and correctly skips when it doesn't.

Screenshots

Before

(raw lifetime-pullCount order — Twilio, Google Sheets, etc. at the top)

After

(download-rate order — attach the screenshot showing the live Store with ballerina-org stdlib modules now ranking first)

Code Quality Checklist

  • Code follows project style guidelines (npm run lint passes)
  • Code is properly formatted (npm run format:check passes)
  • TypeScript compilation succeeds (npx tsc --noEmit)
  • No console.log statements (except console.warn/console.error)
  • Comments added for complex logic
  • Self-review completed

Documentation

  • README updated (if needed)
  • CHANGELOG updated (if needed)
  • Documentation added/updated (if needed)
  • JSDoc comments added for new functions

Performance Impact

  • No performance impact
  • Performance improved
  • Performance degraded (explain below)

Details: "Most Popular" (the default sort) now always takes the full-fetch path instead of a fast, server-sorted single page — it needs the complete catalog in memory to rank by the precomputed data correctly. This makes the default homepage load noticeably slower (several seconds for the full fetch, vs. near-instant before). This tradeoff was discussed and accepted as part of the design; the real fix, if this cost proves unacceptable, would be server-side scoring or pagination-aware computation rather than more client-side optimization.

Breaking Changes

  • No breaking changes
  • Breaking changes (describe below)

Details: Not a breaking API change, but a real behavior change: the default "Most Popular" order changes significantly. Standard-library (ballerina-org) modules, which release far more often than third-party connectors, now rank above high-lifetime-usage connectors like Twilio — e.g. ballerina/time at ~780 downloads/day vs. ballerinax/twilio at ~1/day despite Twilio's far higher total usage. This was demonstrated and discussed with the team and is expected/accepted behavior for this version, not a bug — flagging it here so reviewers aren't surprised.

Additional Notes

Still open, not blocking this PR but worth tracking:

  • Exact monthly schedule and who reviews/merges the automated PR — the current cron (1st of month, 02:00 UTC) is a placeholder
  • This workflow needs "Read and write permissions" and "Allow GitHub Actions to create and approve pull requests" enabled in repo settings for the scheduled PR step to actually work — please confirm these are set on this repo, since they had to be manually enabled during testing on a personal fork

@coderabbitai

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: d0a21321-2f52-41ad-88c6-22177a9c4b63

  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


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

@daneshk
daneshk requested a review from sm1990 October 1, 2026 14:57
Comment thread scripts/generate-ranking-data.js Outdated
Comment thread scripts/generate-ranking-data.js

const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error at offset ${offset}: ${response.status}`);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

do the response contains actual error. If so shall we include it in the Error object as well

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Same fix as above both now use the shared readErrorBody() helper.

Comment thread src/lib/rest-client/rest-client.ts Outdated
Comment thread src/ranking-data.json Outdated
"maturityMinAgeDays": 15
},
"packages": {
"ballerina/http": {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

shall we order this in the alphabetical order. so it is easier to find the diff in the next run.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done . sorted by "org/name" key before writing the file. Regenerated ranking-data.json so the committed version reflects it.

Comment thread public/ranking-data.json
@@ -0,0 +1,5853 @@
{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

is it the right place to add it? it should inside public/ directory. @sm1990

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

+1. Anyone else needing the same sorting can refer the json then.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done. Moved ranking-data.json to public/ and switched to runtime fetching with in-memory caching, only for “Most Popular”. Verified in the browser with no extra requests on other sorts.

Also fixed the workflow add-paths to use the new public/ location.

daneshk
daneshk previously approved these changes Oct 2, 2026
@daneshk daneshk closed this Oct 2, 2026
@daneshk daneshk reopened this Oct 2, 2026
@daneshk
daneshk merged commit 93a6e89 into wso2:main Oct 2, 2026
14 checks passed
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.

3 participants