Skip to content

Commit 984600b

Browse files
authored
update llms content, move libraries data to llms-full.txt file (#2229)
1 parent 4d3e1ce commit 984600b

2 files changed

Lines changed: 37 additions & 92 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@ out/
2727
tsconfig.tsbuildinfo
2828

2929
# llms.txt
30-
public/llms.txt
30+
public/llms.txt
31+
public/llms-full.txt

scripts/generate-llms.ts

Lines changed: 35 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -7,100 +7,35 @@ import { getNewArchSupportStatus, NewArchSupportStatus } from '~/util/newArchSta
77

88
import data from '../assets/data.json';
99

10-
const OUTPUT_PATH = path.resolve('public', 'llms.txt');
10+
const LLMS_PATH = path.resolve('public', 'llms.txt');
11+
const LLMS_FULL_PATH = path.resolve('public', 'llms-full.txt');
12+
1113
const API_DOCUMENTATION = await fs.readFile('API.md', 'utf8');
14+
const README_MARKDOWN = await fs.readFile('README.md', 'utf8');
1215

1316
const INTRODUCTION = `# reactnative.directory
1417
15-
React Native Directory is a website where you can browse through all the libraries that are compatible with React Native.
16-
17-
## Library fields description
18-
19-
### ⚙️ General
20-
21-
- #### ❗ \`githubUrl\` **(required)**
22-
23-
**(string)** - URL to the package GitHub repository (currently other Git hosts are not supported).
24-
25-
> [!WARNING]
26-
> Package also needs to be published to the NPM registry, because it is a source of crucial data for the directory.
27-
28-
- #### \`npmPkg\`
29-
30-
**(string)** - npm package name, by default GitHub repository name will be used. Example: \`"@expo/react-native-action-sheet"\`.
31-
32-
> [!TIP]
33-
> Fill \`npmPkg\` only when the GitHub repository name is different from the name of package published to npm, or the package is a part of monorepo.
34-
35-
- #### \`examples\`
36-
**(array of strings)** - URLs to example projects or Snacks which demonstrates the library.
37-
- #### \`images\`
38-
39-
**(array of strings)** - URLs to static images or GIFs that shows the library functionality.
40-
41-
> [!TIP]
42-
> Please do not add logotypes or other branding materials to the \`images\` array, and please avoid linking multiple assets which shows the same feature.
43-
44-
### 📱 Platforms
18+
React Native Directory is a website where you can browse through all the libraries that are compatible with React Native.`;
4519

46-
- #### \`android\`
47-
**(boolean)** - works on Android device.
48-
- #### \`ios\`
49-
**(boolean)** - works on iOS device.
50-
- #### \`web\`
51-
**(boolean)** - can be used with [\`react-native-web\`](https://github.com/necolas/react-native-web).
52-
53-
### 🖥️ Out-of-tree Platforms
54-
55-
> [!IMPORTANT]
56-
> Adding out-of-tree platforms support requires an example or link to the app which uses the library on the given platform.
57-
58-
- #### \`windows\`
59-
**(boolean)** - can be used with [\`react-native-windows\`](https://github.com/microsoft/react-native-windows).
60-
- #### \`macos\`
61-
**(boolean)** - can be used with [\`react-native-macos\`](https://github.com/microsoft/react-native-macos).
62-
- #### \`tvos\`
63-
**(boolean)** - can be used with [\`react-native-tvos\`](https://github.com/react-native-tvos/react-native-tvos).
64-
- #### \`visionos\`
65-
**(boolean)** - can be used with [\`react-native-visionos\`](https://github.com/callstack/react-native-visionos).
66-
67-
### ✅ Compatibility
68-
69-
> [!TIP]
70-
> **Any** library can be used with Expo, if you use dev clients or prebuild.
71-
72-
- #### \`expoGo\`
73-
**(boolean)** - works with [Expo Go](https://docs.expo.dev/get-started/expo-go/) — an open-source sandbox app, without using [dev clients](https://docs.expo.dev/develop/development-builds/introduction/) or [prebuild](https://docs.expo.dev/workflow/continuous-native-generation/).
74-
- #### \`fireos\`
75-
**(boolean)** - works on Amazon Fire OS.
76-
- #### \`horizon\`
77-
**(boolean)** - works on Meta Horizon OS.
78-
- #### \`vegaos\`
79-
**(boolean|string)** - works with [Vega OS](https://developer.amazon.com/apps-and-games/vega). It can also be a string containing npm package name, if a separate/additional package is required for full support.
80-
81-
### 🏷️ Tags
20+
function normalizeNewlines(text: string) {
21+
return text.replace(/\r\n/g, '\n');
22+
}
8223

83-
- #### \`unmaintained\`
84-
**(boolean)** - signify that a library is no longer maintained. You can provide alternative or replacement libraries with the \`alternatives\` field, if needed.
85-
- #### \`dev\`
86-
**(boolean)** - signify that a library is a development tool or is only a part of development process.
87-
- #### \`template\`
88-
**(boolean)** - signify that a library is a new project template.
89-
- #### \`configPlugin\`
90-
**(boolean \\| string \\[URL to third-party config plugin\\])** - Indicates if the library includes an [Expo config plugin](https://docs.expo.dev/config-plugins/introduction/). If the plugin is provided by a third party, supply the URL as a string. This field is optional and will be detected automatically if omitted.
91-
- #### \`newArchitecture\`
92-
**(boolean|'new-arch-only')** - signify that a library supports both, or not, the New Architecture and the Old Architecture or only the New Architecture. Skipping the field will result in "untested" status, unless automatic support detection returned a result. You can provide additional context with the \`newArchitectureNote\` field, if needed.
24+
function extractReadmeSection(heading: string) {
25+
const md = normalizeNewlines(README_MARKDOWN);
9326

94-
> [!TIP]
95-
> Set \`newArchitecture\` field only when automatic architecture detection fails for your package, despite it supports the New Architecture.
27+
const headingToFind = `## ${heading}`;
28+
const startIndex = md.indexOf(headingToFind);
9629

97-
### 📝 Additional context for tags
30+
if (startIndex === -1) {
31+
throw new Error(`Could not find section heading in README.md: ${headingToFind}`);
32+
}
9833

99-
- #### \`newArchitectureNote\`
100-
**(string)** - provide a note for the New Architecture support status, if a boolean \`"true"\` or \`"false"\` is not sufficient to describe the state of New Architecture support.
34+
const fromStart = md.slice(startIndex);
35+
const nextSectionIndex = fromStart.search(/\n##\s+/);
10136

102-
- #### \`alternatives\`
103-
**(array of strings)** - provide a list of alternatives to the library. eg: \`["expo-camera", "react-native-vision-camera"]\`. This is used to provide a list of alternatives to a library if it is unmaintained or does not support the New Architecture.`;
37+
return (nextSectionIndex === -1 ? fromStart : fromStart.slice(0, nextSectionIndex)).trim();
38+
}
10439

10540
const NEW_ARCHITECTURE_STATUS_LABELS: Record<NewArchSupportStatus, string> = {
10641
[NewArchSupportStatus.NewArchOnly]: 'Only Supports New Architecture',
@@ -121,7 +56,8 @@ function formatRecord(library: LibraryType): string {
12156
const { npmPkg, npm, github, githubUrl } = library;
12257

12358
return [
124-
`[${npmPkg}](${githubUrl}): ${github.description ?? 'No description'}`,
59+
`## [${npmPkg}](${githubUrl})\n`,
60+
`${github.description ?? 'No description'}\n`,
12561
`Platforms: ${platforms.join(', ')}`,
12662
compatibility.length > 0 ? `Compatibility: ${compatibility.join(', ')}` : undefined,
12763
`New Architecture: ${newArch}`,
@@ -185,25 +121,33 @@ function formatDownloads({ npm }: LibraryType) {
185121
return parts.join(', ');
186122
}
187123

188-
async function generateLlmsFile() {
124+
async function generateLLMSFiles() {
125+
const librariesFields = extractReadmeSection('How do I add a library?');
126+
const llmsContent = [INTRODUCTION, librariesFields, API_DOCUMENTATION].join('\n\n');
127+
128+
await fs.writeFile(LLMS_PATH, `${llmsContent}\n`, 'utf8');
129+
130+
console.log(`✅ Generated ${path.relative(process.cwd(), LLMS_PATH)}`);
131+
189132
const { libraries } = data as DataAssetType;
190133

191134
const entries = libraries
192135
.filter(library => !library.template)
193136
.map(library => formatRecord(library));
194137

195-
const content = [
138+
const llmsFullContent = [
196139
INTRODUCTION,
140+
librariesFields,
197141
API_DOCUMENTATION,
198142
'# List of available libraries',
199-
entries.join('\n\n---\n\n'),
143+
entries.join('\n\n'),
200144
].join('\n\n');
201145

202-
await fs.writeFile(OUTPUT_PATH, `${content}\n`, 'utf8');
146+
await fs.writeFile(LLMS_FULL_PATH, `${llmsFullContent}\n`, 'utf8');
203147

204148
console.log(
205-
`✅ Generated ${entries.length} entries in ${path.relative(process.cwd(), OUTPUT_PATH)}`
149+
`✅ Generated ${path.relative(process.cwd(), LLMS_PATH)} with ${entries.length} libraries data`
206150
);
207151
}
208152

209-
await generateLlmsFile();
153+
await generateLLMSFiles();

0 commit comments

Comments
 (0)