From e1b361fcb063dc31dfebd47a06fbffdecfa357be Mon Sep 17 00:00:00 2001 From: Bartosz Kaszubowski Date: Fri, 7 Nov 2025 21:54:10 +0100 Subject: [PATCH 1/3] rewrite check resource script, add and update libs --- react-native-libraries.json | 193 +++++++++++++++++++++++++---- react-native-libraries.schema.json | 96 ++++++-------- scripts/check-resources.ts | 66 ++++++---- 3 files changed, 248 insertions(+), 107 deletions(-) diff --git a/react-native-libraries.json b/react-native-libraries.json index 40fe38a0d..1d25ca3bb 100644 --- a/react-native-libraries.json +++ b/react-native-libraries.json @@ -5704,7 +5704,7 @@ { "githubUrl": "https://github.com/mcodex/react-native-rooster", "examples": ["https://github.com/mCodex/react-native-rooster/tree/master/example"], - "images": ["https://raw.githubusercontent.com/mCodex/react-native-rooster/master/demo.gif"], + "images": ["https://raw.githubusercontent.com/mCodex/react-native-rooster/master/example.gif"], "ios": true, "android": true, "expoGo": true, @@ -5873,9 +5873,9 @@ }, { "githubUrl": "https://github.com/AndreiCalazans/rn-tooltip", - "examples": ["https://github.com/AndreiCalazans/rn-tooltip", "rn-tooltip"], + "examples": ["https://github.com/AndreiCalazans/rn-tooltip"], "images": [ - "https://raw.githubusercontent.com/AndreiCalazans/rn-tooltip/HEAD/tooltipExample.gif" + "https://raw.githubusercontent.com/AndreiCalazans/rn-tooltip/master/tooltipExample.gif" ], "ios": true, "android": true, @@ -10395,7 +10395,7 @@ "images": ["https://github.com/anday013/react-native-otp-entry/blob/main/otp_demo.gif"], "ios": true, "android": true, - "web": "true", + "web": true, "expoGo": true, "newArchitecture": true }, @@ -12282,9 +12282,6 @@ "https://github.com/PostHog/posthog-js/tree/main/examples/example-expo-53", "https://github.com/PostHog/posthog-js/tree/main/examples/example_rn_macos" ], - "images": [ - "https://posthog.com/static/a31f7db2abf56ba7e82e88b0d47ea0be/929d0/screenshot-product-analytics.webp" - ], "ios": true, "android": true, "web": true, @@ -12335,7 +12332,7 @@ "githubUrl": "https://github.com/mehuljetani/react-native-typing-animated-text", "examples": ["https://github.com/mehuljetani/react-native-typing-animated-text"], "images": [ - "https://github.com/mehuljetani/react-native-typing-animated-text/blob/main/src/assets/demo.gif" + "https://miro.medium.com/v2/1%2ArEKhCdFKhcI7mhUdfot6QQ.gif" ], "ios": true, "android": true @@ -12344,7 +12341,7 @@ "githubUrl": "https://github.com/mehuljetani/react-native-custom-animated-accordion", "examples": ["https://github.com/mehuljetani/react-native-custom-animated-accordion"], "images": [ - "https://github.com/mehuljetani/react-native-custom-animated-accordion/blob/main/src/assets/accord.gif" + "https://miro.medium.com/v2/1*HUF-HMdhht8WRz5gFtnreQ.gif" ], "ios": true, "android": true @@ -12790,7 +12787,6 @@ }, { "githubUrl": "https://github.com/HichamELBSI/react-native-body-highlighter", - "examples": ["https://staging-snack.expo.dev/@hichamelbsi/react-native-body-highlighter"], "images": [ "https://github.com/HichamELBSI/react-native-body-highlighter/raw/main/docs/screenshots/example-female-front.PNG", "https://github.com/HichamELBSI/react-native-body-highlighter/raw/main/docs/screenshots/example-female-back.PNG", @@ -15640,7 +15636,6 @@ { "githubUrl": "https://github.com/Sharcoux/navigation/tree/master/packages/react-native", "npmPkg": "@react-native-assets/navigation", - "examples": ["https://snack.expo.dev/@cantoo/react-native-navigation"], "images": ["https://github.com/Sharcoux/navigation/blob/master/example/navigation.gif"], "android": true, "ios": true, @@ -15731,7 +15726,7 @@ }, { "githubUrl": "https://github.com/developit/mitt", - "examples": ["http://codepen.io/developit/pen/rjMEwW?editors=0110"], + "examples": ["https://codepen.io/developit/pen/rjMEwW?editors=0110"], "ios": true, "android": true, "web": true, @@ -17679,8 +17674,7 @@ { "githubUrl": "https://github.com/alexrus28996/react-native-threadforge/tree/main/packages/react-native-threadforge", "examples": [ - "https://github.com/alexrus28996/react-native-threadforge", - "https://snack.expo.dev/@alexrus28996/threadforge-demo" + "https://github.com/alexrus28996/react-native-threadforge" ], "images": [ "https://raw.githubusercontent.com/alexrus28996/react-native-threadforge/main/docs/assets/threadforge-demo.gif" @@ -18035,9 +18029,7 @@ }, { "githubUrl": "https://github.com/mCodex/react-native-sized-webview", - "examples": [ - "https://github.com/mCodex/react-native-sized-webview/tree/main/example" - ], + "examples": ["https://github.com/mCodex/react-native-sized-webview/tree/main/example"], "ios": true, "android": true, "web": true, @@ -18049,7 +18041,9 @@ { "githubUrl": "https://github.com/khokanuzzaman/react-native-zero-permission-picker", "npmPkg": "react-native-files-picker", - "examples": ["https://github.com/khokanuzzaman/react-native-zero-permission-picker/tree/main/example"], + "examples": [ + "https://github.com/khokanuzzaman/react-native-zero-permission-picker/tree/main/example" + ], "images": [ "https://raw.githubusercontent.com/khokanuzzaman/react-native-zero-permission-picker/main/docs/screenshots/example-app-main.jpeg", "https://raw.githubusercontent.com/khokanuzzaman/react-native-zero-permission-picker/main/docs/screenshots/selected-item.jpeg" @@ -18072,9 +18066,7 @@ { "githubUrl": "https://github.com/TheWidlarzGroup/react-native-voice-agent", "npmPkg": "react-native-audio-agent", - "examples": [ - "https://github.com/TheWidlarzGroup/react-native-voice-agent/tree/main/example" - ], + "examples": ["https://github.com/TheWidlarzGroup/react-native-voice-agent/tree/main/example"], "ios": true, "android": true, "newArchitecture": true @@ -18090,7 +18082,6 @@ }, { "githubUrl": "https://github.com/tristanmanchester/react-native-dotgrid", - "npmPkg": "react-native-dotgrid", "examples": ["https://github.com/tristanmanchester/react-native-dotgrid/tree/main/example"], "images": [ "https://raw.githubusercontent.com/tristanmanchester/react-native-dotgrid/main/demos/wave.webp", @@ -18111,12 +18102,166 @@ { "githubUrl": "https://github.com/adelbeke/react-native-speech-to-text", "npmPkg": "@dbkable/react-native-speech-to-text", + "examples": ["https://github.com/adelbeke/react-native-speech-to-text/tree/main/example"], + "ios": true, + "android": true, + "newArchitecture": "new-arch-only", + "configPlugin": true + }, + { + "githubUrl": "https://github.com/JairajJangle/react-native-navigation-mode", + "examples": ["https://github.com/JairajJangle/react-native-navigation-mode/tree/main/example"], + "images": [ + "https://raw.githubusercontent.com/JairajJangle/react-native-navigation-mode/refs/heads/main/.github/assets/buttons.png", + "https://raw.githubusercontent.com/JairajJangle/react-native-navigation-mode/refs/heads/main/.github/assets/gesture.png" + ], + "ios": true, + "android": true, + "newArchitecture": "new-arch-only" + }, + { + "githubUrl": "https://github.com/Flagsmith/flagsmith-js-client/tree/main/lib/react-native-flagsmith", + "examples": ["https://github.com/Flagsmith/flagsmith-js-examples/tree/main/reactnative"], + "ios": true, + "android": true + }, + { + "githubUrl": "https://github.com/BlinkID/blinkid-react-native/tree/master/BlinkID", + "npmPkg": "@microblink/blinkid-react-native", + "ios": true, + "android": true + }, + { + "githubUrl": "https://github.com/k-tomoyasu/react-native-oss-license", + "images": [ + "https://raw.githubusercontent.com/k-tomoyasu/react-native-oss-license/master/screenshots/settings-bundle-list.png", + "https://raw.githubusercontent.com/k-tomoyasu/react-native-oss-license/master/screenshots/about-libraries.png" + ], + "ios": true, + "android": true + }, + { + "githubUrl": "https://github.com/roam-ai/roam-reactnative", + "ios": true, + "android": true + }, + { + "githubUrl": "https://github.com/craftzdog/pouchdb-adapter-react-native-sqlite", + "examples": [ + "https://github.com/craftzdog/pouchdb-adapter-react-native-sqlite/tree/master/example" + ], + "ios": true, + "android": true + }, + { + "githubUrl": "https://github.com/bitmovin/bitmovin-player-react-native", "examples": [ - "https://github.com/adelbeke/react-native-speech-to-text/tree/main/example" + "https://github.com/bitmovin/bitmovin-player-react-native/tree/development/example" + ], + "ios": true, + "android": true, + "tvos": true, + "fireos": true + }, + { + "githubUrl": "https://github.com/ahmedbna/ui", + "npmPkg": "bna-ui", + "images": [ + "https://cdn.jsdelivr.net/gh/ahmedbna/bna-ui-demo/bna-ui-header.png" + ], + "dev": true, + "ios": true, + "android": true, + "web": true, + "expoGo": true + }, + { + "githubUrl": "https://github.com/microsoft/react-native-winrt/tree/main/package", + "npmPkg": "react-native-winrt", + "images": [ + "https://raw.githubusercontent.com/microsoft/react-native-winrt/main/samples/RNWinRTTestApp/images/sample-app.png" + ], + "examples": [ + "https://github.com/microsoft/react-native-winrt/tree/main/samples/RNWinRTTestApp" + ], + "windows": true + }, + { + "githubUrl": "https://github.com/Anyline/anyline-ocr-react-native-module/tree/master/plugin", + "npmPkg": "anyline-ocr-react-native-module", + "examples": [ + "https://github.com/Anyline/anyline-ocr-react-native-module/tree/master/example/RNExampleApp" + ], + "ios": true, + "android": true + }, + { + "githubUrl": "https://github.com/stripe/stripe-terminal-react-native", + "npmPkg": "@stripe/stripe-terminal-react-native", + "examples": [ + "https://github.com/stripe/stripe-terminal-react-native/tree/main/example-app" + ], + "ios": true, + "android": true + }, + { + "githubUrl": "https://github.com/AgoraIO-Extensions/react-native-agora", + "examples": [ + "https://github.com/AgoraIO-Extensions/react-native-agora/tree/main/example" + ], + "ios": true, + "android": true + }, + { + "githubUrl": "https://github.com/star-micronics/react-native-star-io10", + "examples": [ + "https://github.com/star-micronics/react-native-star-io10/tree/master/example" + ], + "ios": true, + "android": true, + "windows": true + }, + { + "githubUrl": "https://github.com/mym0404/react-native-naver-map", + "npmPkg": "@mj-studio/react-native-naver-map", + "examples": [ + "https://github.com/mym0404/react-native-naver-map/tree/main/example" + ], + "images": [ + "https://raw.githubusercontent.com/mym0404/image-archive/master/202404240329848.gif" ], "ios": true, "android": true, - "newArchitecture": "new-arch-only", "configPlugin": true + }, + { + "githubUrl": "https://github.com/BonnierNews/react-native-3d-model-view", + "examples": [ + "https://github.com/BonnierNews/react-native-3d-model-view/tree/master/example" + ], + "images": [ + "https://raw.githubusercontent.com/BonnierNews/react-native-3d-model-view/refs/heads/master/screenshots/modelview.png", + "https://raw.githubusercontent.com/BonnierNews/react-native-3d-model-view/refs/heads/master/screenshots/arview.png" + ], + "ios": true + }, + { + "githubUrl": "https://github.com/reactnativecn/react-native-update", + "examples": [ + "https://github.com/reactnativecn/react-native-update/tree/master/Example/expoUsePushy", + "https://github.com/reactnativecn/react-native-update/tree/master/Example/harmony_use_pushy" + ], + "ios": true, + "android": true + }, + { + "githubUrl": "https://github.com/victorsoares96/epubjs-react-native", + "npmPkg": "@epubjs-react-native/core", + "examples": [ + "https://github.com/victorsoares96/epubjs-react-native/tree/master/example-bare", + "https://github.com/victorsoares96/epubjs-react-native/tree/master/example-expo" + ], + "ios": true, + "android": true } ] diff --git a/react-native-libraries.schema.json b/react-native-libraries.schema.json index d9ea87087..a786b82ca 100644 --- a/react-native-libraries.schema.json +++ b/react-native-libraries.schema.json @@ -11,79 +11,72 @@ "required": [ "githubUrl" ], + "additionalProperties": false, "properties": { "githubUrl": { "$id": "#/items/properties/githubUrl", "type": "string", "title": "Package GitHub repository URL", "default": "", + "pattern": "^(https?://)?(www\\.)?github\\.com/[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+(/tree/[A-Za-z0-9_.@%\\-/]+)?/?$", "examples": [ - "https://github.com/joshswan/react-native-autolink" - ], - "pattern": "^(.*)$" + "https://github.com/joshswan/react-native-autolink", + "https://github.com/GetStream/stream-chat-react-native/tree/develop/package/expo-package" + ] }, "ios": { "$id": "#/items/properties/ios", "type": "boolean", "title": "Package supports iOS", - "default": false, - "examples": [ - true - ] + "default": false }, "android": { "$id": "#/items/properties/android", "type": "boolean", "title": "Package supports Android", - "default": false, - "examples": [ - true - ] + "default": false + }, + "web": { + "$id": "#/items/properties/android", + "type": "boolean", + "title": "Package supports Web (react-native-web)", + "default": false }, "windows": { "$id": "#/items/properties/windows", "type": "boolean", "title": "Package supports Windows (react-native-windows)", - "default": false, - "examples": [ - true - ] + "default": false }, "macos": { "$id": "#/items/properties/macos", "type": "boolean", "title": "Package supports macOS (react-native-macos)", - "default": false, - "examples": [ - true - ] + "default": false }, "tvos": { "$id": "#/items/properties/tvos", "type": "boolean", "title": "Package supports tvOS (react-native-tvos)", - "default": false, - "examples": [ - true - ] + "default": false + }, + "visionos": { + "$id": "#/items/properties/tvos", + "type": "boolean", + "title": "Package supports visionOS (react-native-visionos)", + "default": false }, "fireos": { "$id": "#/items/properties/fireos", "type": "boolean", - "title": "Package is compatible with Fire OS", - "default": false, - "examples": [ - true - ] + "title": "Package is compatible with Amazon Fire OS", + "default": false }, "horizon": { "$id": "#/items/properties/horizon", "type": "boolean", "title": "Package is compatible with Meta Horizon OS", - "default": false, - "examples": [ - true - ] + "default": false }, "vegaos": { "$id": "#/items/properties/vegaos", @@ -91,7 +84,7 @@ "boolean", "string" ], - "title": "Package is compatible with Vega OS. Can be a boolean, or string containing the dedicated package package name from npm registry.", + "title": "Package is compatible with Amazon Vega OS. Can be a boolean, or string containing the dedicated package package name from npm registry.", "default": false, "examples": [ true, @@ -102,10 +95,7 @@ "$id": "#/items/properties/expo", "type": "boolean", "title": "Package is compatible with Expo Go", - "default": false, - "examples": [ - true - ] + "default": false }, "examples": { "$id": "#/items/properties/examples", @@ -140,7 +130,7 @@ "https://reactnative.dev/img/homepage/phones.png", "https://github.com/mattermost/react-native-paste-input/blob/master/example/gifs/iOSPasteInput.gif?raw=true" ], - "pattern": "^(http(s?):)(\\w|\\/|\\.|:|-|%|\\+|\\*)+\\.(?:jp(e?)g|gif|png|webp|JP(E?)G|GIF|PNG|WEBP)(\\?\\S*)?$" + "pattern": "^(http(s?):)(\\w|/|\\.|:|-|%|\\+|\\*)+\\.(?:jp(e?)g|gif|png|webp|JP(E?)G|GIF|PNG|WEBP)(\\?\\S*)?$" } }, "npmPkg": { @@ -155,34 +145,21 @@ }, "unmaintained": { "$id": "#/items/properties/unmaintained", - "type": [ - "boolean", - "string" - ], + "type": "boolean", "title": "Package is unmaintained or archived", - "default": false, - "examples": [ - true, - "expo-image" - ] + "default": false }, "dev": { "$id": "#/items/properties/dev", "type": "boolean", - "title": "Package is a Development Tool (should be installed as 'devDependency')", - "default": false, - "examples": [ - true - ] + "title": "Package is a Development Tool (should be installed as 'devDependency' or used via `npx/bunx`)", + "default": false }, "template": { "$id": "#/items/properties/template", "type": "boolean", - "title": "Package is a project template", - "default": false, - "examples": [ - true - ] + "title": "Entry is a project template", + "default": false }, "newArchitecture": { "$id": "#/items/properties/newArchitecture", @@ -190,7 +167,8 @@ "boolean", "string" ], - "title": "Package supports New Architecture", + "enum": [true, false, "new-arch-only"], + "title": "Package supports New Architecture. Can be a boolean, or 'new-arch-only' string, if package only supports New Architecture.", "default": false, "examples": [ true, @@ -217,7 +195,7 @@ "default": false, "examples": [ true, - "link to third-party config plugin" + "https://github.com/expo/config-plugins/tree/main/packages/react-native-pdf" ] }, "alternatives": { diff --git a/scripts/check-resources.ts b/scripts/check-resources.ts index b3916d244..bdd3eddb6 100644 --- a/scripts/check-resources.ts +++ b/scripts/check-resources.ts @@ -3,39 +3,57 @@ import { fetch } from 'bun'; import { type LibraryDataEntryType } from '~/types'; import libraries from '../react-native-libraries.json'; -import { sleep } from './helpers'; -async function runThrottledFetches(libraries: LibraryDataEntryType[], delayMs = 50) { - const urlList: string[] = []; +const CONCURRENCY = 8; - for (const lib of libraries) { - if (lib.examples) { - for (const exampleUrl of lib.examples) { - urlList.push(exampleUrl); - } +async function fetchUrl(url: string) { + const controller = new AbortController(); + const timeout = setTimeout(() => controller.abort(), 10000); + + try { + const res = await fetch(url, { signal: controller.signal }); + if (res.status !== 200) { + console.warn(`❌ ${url} → ${res.status}`); } - if (lib.images) { - for (const imgUrl of lib.images) { - urlList.push(imgUrl); - } + } catch (err) { + if (err instanceof DOMException) { + console.warn(`❌ ${url} failed to fetch:`, err.message); + } else { + console.warn(`❌ ${url} failed to fetch!`); } + } finally { + clearTimeout(timeout); } +} + +async function runFetches(libraries: LibraryDataEntryType[]) { + const urls = libraries.flatMap(lib => [...(lib.examples ?? []), ...(lib.images ?? [])]); + + console.log(`⬇️ Fetching ${urls.length} URLs with concurrency of ${CONCURRENCY} requests`); - console.log(`⬇️ Attempting to fetch examples and images (${urlList.length} URLs)`); + let current = 0; + let completed = 0; - for (const url of urlList) { - try { - const response = await fetch(url); - if (response.status !== 200) { - console.warn(`${url} returned ${response.status}`); + async function fetcher() { + while (true) { + const index = current++; + if (index >= urls.length) { + break; + } + + await fetchUrl(urls[index]); + + completed++; + if (completed % 100 === 0 || completed === urls.length) { + console.log(`⏩ ${completed}/${urls.length} done`); } - } catch (err: any) { - console.warn(`${url} errored!`, err); } - await sleep(delayMs); } + + const batches = Array.from({ length: CONCURRENCY }, fetcher); + await Promise.all(batches); + + console.log('✅ All fetches finished!'); } -runThrottledFetches(libraries).catch(err => { - console.error('❌ Unexpected error in throttled fetcher:', err); -}); +runFetches(libraries).catch(err => console.error('❌ Unexpected error:', err)); From 6a4340c78a6381e75a6a43404325595bb0ca21ca Mon Sep 17 00:00:00 2001 From: Bartosz Kaszubowski Date: Fri, 7 Nov 2025 22:02:35 +0100 Subject: [PATCH 2/3] fix schema --- react-native-libraries.schema.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/react-native-libraries.schema.json b/react-native-libraries.schema.json index a786b82ca..6f2121c11 100644 --- a/react-native-libraries.schema.json +++ b/react-native-libraries.schema.json @@ -1,9 +1,8 @@ { - "definitions": {}, "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://github.com/react-native-community/directory/blob/main/react-native-libraries.schema.json", "type": "array", - "title": "React Native Directory entries", + "title": "React Native Directory entries list", "items": { "$id": "#/items", "type": "object", @@ -37,7 +36,7 @@ "default": false }, "web": { - "$id": "#/items/properties/android", + "$id": "#/items/properties/web", "type": "boolean", "title": "Package supports Web (react-native-web)", "default": false @@ -61,7 +60,7 @@ "default": false }, "visionos": { - "$id": "#/items/properties/tvos", + "$id": "#/items/properties/visionos", "type": "boolean", "title": "Package supports visionOS (react-native-visionos)", "default": false From 4f53d5a8b67e0ed7ef560d5db15b21aa9a6d6122 Mon Sep 17 00:00:00 2001 From: Bartosz Kaszubowski Date: Fri, 7 Nov 2025 22:06:39 +0100 Subject: [PATCH 3/3] remove duplicate entry --- react-native-libraries.json | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/react-native-libraries.json b/react-native-libraries.json index 1d25ca3bb..feb7299b9 100644 --- a/react-native-libraries.json +++ b/react-native-libraries.json @@ -18108,17 +18108,6 @@ "newArchitecture": "new-arch-only", "configPlugin": true }, - { - "githubUrl": "https://github.com/JairajJangle/react-native-navigation-mode", - "examples": ["https://github.com/JairajJangle/react-native-navigation-mode/tree/main/example"], - "images": [ - "https://raw.githubusercontent.com/JairajJangle/react-native-navigation-mode/refs/heads/main/.github/assets/buttons.png", - "https://raw.githubusercontent.com/JairajJangle/react-native-navigation-mode/refs/heads/main/.github/assets/gesture.png" - ], - "ios": true, - "android": true, - "newArchitecture": "new-arch-only" - }, { "githubUrl": "https://github.com/Flagsmith/flagsmith-js-client/tree/main/lib/react-native-flagsmith", "examples": ["https://github.com/Flagsmith/flagsmith-js-examples/tree/main/reactnative"],