### Start Development Server Source: https://github.com/textualize/textualize.io/blob/main/README.md Starts the local development server for Textualize.io using npm. The site will be accessible at http://localhost:3000. ```bash npm run dev ``` -------------------------------- ### Install Node.js and Dependencies Source: https://github.com/textualize/textualize.io/blob/main/README.md Installs Node.js version 16, sets it as the active version, and installs project dependencies using npm. This is a prerequisite for running the development server. ```bash nvm install 16 && nvm use 16 npm i ``` -------------------------------- ### Python LRU Cache Implementation for Performance Source: https://github.com/textualize/textualize.io/blob/main/data/blog/2022-08-01---7-things-about-terminals.md Demonstrates how to use the `@lru_cache` decorator from Python's `functools` module to cache function return values and improve performance. It highlights the speed of the CPython implementation and provides an example of a function that benefits from caching, emphasizing the importance of checking `cache_info()` for effective caching. ```python from functools import lru_cache @lru_cache(maxsize=1000) def calculate_overlap(rect1, rect2): # ... implementation to calculate overlap ... pass # Example usage: # cache_info = calculate_overlap.cache_info() ``` -------------------------------- ### Import Team Component and Get Static Props - TypeScript Source: https://github.com/textualize/textualize.io/blob/main/src/pages/about-us.mdx Imports the Team component for rendering and exports a function to fetch team member data for static generation. This setup is typical for Next.js pages requiring server-side data fetching at build time. ```typescript import { Team } from "../components/page-specific/abous-us/team" export { getTeamMembersStaticProps as getStaticProps } from "../services/nextjs-bridge/about-us" ``` -------------------------------- ### In-Memory Cache Service Source: https://context7.com/textualize/textualize.io/llms.txt A simple in-memory cache implementation using a Map to store and retrieve data within a single application lifecycle. It provides functions to check for a key's existence, get a value (with an optional default), set a value, and delete a key. ```typescript type CacheKey = string const cacheStore = new Map() export async function has(key: CacheKey): Promise { return cacheStore.has(key) } export async function get(key: CacheKey, defaultValue: T | null = null): Promise { const value = cacheStore.get(key) return value === undefined ? defaultValue : value } export async function set(key: CacheKey, value: T): Promise { cacheStore.set(key, value) } export async function del(key: CacheKey): Promise { cacheStore.delete(key) } // Usage: // const cacheKey = "blog-posts" // const cached = await cacheSharedServices.get(cacheKey) // if (cached) return cached // const data = await fetchData() // await cacheSharedServices.set(cacheKey, data) // return data ``` -------------------------------- ### Optimize UI Updates using Python Dictionary Views Source: https://github.com/textualize/textualize.io/blob/main/data/blog/2022-08-01---7-things-about-terminals.md Demonstrates how to use Python dictionary set operations to identify changes between two states efficiently. This technique is used in Textual to calculate modified screen regions by comparing render maps. ```python old_map = {'a': 1, 'b': 2, 'c': 3} new_map = {'b': 2, 'c': 4, 'd': 5} # Find items that are new or changed using symmetric difference changed_items = old_map.items() ^ new_map.items() print(changed_items) ``` -------------------------------- ### Format Code with Prettier Source: https://github.com/textualize/textualize.io/blob/main/README.md Runs Prettier to automatically format the project's code. This command should be executed before committing changes to ensure code style consistency. ```bash npm run format:fix ``` -------------------------------- ### Next.js Home Page with ISR (TypeScript) Source: https://context7.com/textualize/textualize.io/llms.txt Demonstrates a Next.js home page implementation utilizing Incremental Static Regeneration (ISR). It fetches project data and the latest blog post using `getStaticProps` and revalidates the page every hour. ```typescript // src/pages/index.tsx import type { GetStaticProps } from "next/types" import { Hero } from "../components/page-specific/home/hero" import { ProjectsIndex } from "../components/page-specific/home/projects-index" import { ProjectsDataContext } from "../contexts/projects-data" import type { BlogPost, ProjectData } from "../domain" import * as blogPostsBackendServices from "../services/backend/blog" import { getCommonStaticProps } from "../services/nextjs-bridge/common-static-props" interface HomePageProps { projectsData: ProjectData[] lastBlogPost: BlogPost } export default function HomePage(props: HomePageProps) { return ( ) } export const getStaticProps: GetStaticProps = async (context) => { const { props: commonProps } = await getCommonStaticProps(context) const blogPosts = await blogPostsBackendServices.blogPosts() return { props: { ...commonProps, lastBlogPost: blogPosts[0], }, revalidate: 3600, // Re-generate page every hour } } ``` -------------------------------- ### Application Configuration and Constants (TypeScript) Source: https://context7.com/textualize/textualize.io/llms.txt Defines application-wide configuration settings, including environment variables for URLs and tracking codes, as well as project-specific constants for identifiers, gallery, and pagination. ```typescript // src/config.ts export const AppConfig = { absoluteUrl: process.env["NEXT_PUBLIC_ABSOLUTE_URL"] || "", fathom: { trackingCode: process.env["NEXT_PUBLIC_FATHOM_TRACKING_CODE"] || "", includedDomains: (process.env["NEXT_PUBLIC_FATHOM_INCLUDED_DOMAINS"] || "").split(","), }, subscribeUrl: "https://textualize.us5.list-manage.com/subscribe/post?...", textualize: { urls: { twitter: "https://twitter.com/textualizeio", github: "https://github.com/Textualize", discord: "https://discord.gg/Enf6Z3qhVr", }, }, } // src/constants.ts export const PROJECT_IDS: readonly ProjectId[] = ["textual", "rich", "rich-cli"] export const PROJECTS_WITH_GALLERY: ProjectId[] = ["textual", "rich"] export const GALLERY_ITEMS_COUNT_PER_PAGE = 5 export const BLOG_ITEMS_COUNT_PER_PAGE = 5 // src/i18n.ts export const PROJECT_NAMES: Record = { "textual": "Textual", "rich": "Rich", "rich-cli": "Rich CLI", } // src/metadata.ts export const TITLE = "Textualize.io" export const DESCRIPTION = "The terminal can be more powerful and beautiful than you ever thought" export const CANONICAL_SITE_URL = "https://www.textualize.io/" ``` -------------------------------- ### Load Project Gallery Items from MDX Source: https://context7.com/textualize/textualize.io/llms.txt Loads gallery items from MDX files within a specified project directory. It parses frontmatter for metadata like title, URLs, and categories, and processes associated images. Dependencies include 'fast-glob', 'gray-matter', and 'image-size'. ```typescript import { promises as fs } from "node:fs" import fastGlob from "fast-glob" import matter from "gray-matter" import imageSizeSync from "image-size" import type { ImageProperties, ProjectGalleryItem, ProjectId } from "../../domain" import { renderMarkdown } from "../../helpers/markdown-helpers" const SUPPORTED_FILE_EXTENSIONS = ["png", "jpg", "jpeg", "gif"] export async function projectGallery(projectId: ProjectId): Promise { const folderPath = `data/projects-galleries/${projectId}` const projectsFiles = await fastGlob("*.mdx", { cwd: folderPath, absolute: true }) return Promise.all( projectsFiles.map((filePath) => galleryProjectFromMarkdownFilePath(projectId, filePath)) ) } async function galleryProjectFromMarkdownFilePath( projectId: ProjectId, filePath: string ): Promise { const itemId = basename(filePath, ".mdx") const fileContent = await fs.readFile(filePath) const { content, data } = matter(fileContent) const categories = (data["categories"] ?? []).map((c: string) => c.toLowerCase()) const image = await galleryItemImageProperties(projectId, itemId) return { projectId, id: itemId, image, description: renderMarkdown(content), title: data["title"], categories, codeUrl: data["codeUrl"] ?? null, websiteUrl: data["websiteUrl"] ?? null, docsUrl: data["docsUrl"] ?? null, stars: null, // Set via attachCurrentStarsCountsToRepositories() } } // Gallery item MDX format (data/projects-galleries/rich/httpie.mdx): // --- // title: HTTPie // codeUrl: https://github.com/httpie/httpie // websiteUrl: https://httpie.io/ // docsUrl: https://httpie.io/docs/cli // categories: [http] // --- // Modern, user-friendly command-line HTTP client for the API era. ``` -------------------------------- ### Define Project Metadata in Markdown Front-Matter Source: https://github.com/textualize/textualize.io/blob/main/src/pages/gallery-instructions.mdx This snippet demonstrates the required YAML front-matter structure for project gallery submissions. It includes the project title, source code URL, and classification categories, followed by a brief project description. ```markdown --- title: Scalene codeUrl: https://github.com/emeryberger/scalene categories: [profiling] --- A high-performance, high-precision CPU, GPU, and memory profiler for Python ``` -------------------------------- ### Gallery Pagination and URL Routing Services Source: https://context7.com/textualize/textualize.io/llms.txt Provides shared services for managing gallery pagination, filtering by category, and constructing navigation URLs. It calculates the total number of pages, aggregates category counts, filters items by category, and generates URL strings for different gallery views. ```typescript import { GALLERY_ITEMS_COUNT_PER_PAGE } from "../../constants" import type { CategoriesWithCount, Category, ProjectGalleryItem, ProjectId } from "../../domain" export function pagesCount(itemsCount: number): number { return Math.ceil(itemsCount / GALLERY_ITEMS_COUNT_PER_PAGE) // 5 items per page } export function projectGalleryCategories(galleryItems: ProjectGalleryItem[]): CategoriesWithCount { const categoriesWithStats: CategoriesWithCount = {} for (const item of galleryItems) { for (const category of item.categories) { categoriesWithStats[category] = (categoriesWithStats[category] || 0) + 1 } } return categoriesWithStats } export function projectGalleryForCategory( galleryItems: ProjectGalleryItem[], category: Category ): ProjectGalleryItem[] { if (category === "all") { return galleryItems.slice() } return galleryItems.filter((item) => item.categories.includes(category)) } // URL patterns: // /textual/gallery -> all items, page 1 // /textual/gallery/2 -> all items, page 2 // /textual/gallery/tui -> "tui" category, page 1 // /textual/gallery/tui/2 -> "tui" category, page 2 export function projectGalleryPageUrl(kwargs: { projectId: ProjectId category: Category page: number }): string { const segments = [kwargs.projectId, "gallery"] if (kwargs.category !== "all") { segments.push(encodeURIComponent(kwargs.category)) } if (kwargs.page > 1) { segments.push(String(kwargs.page)) } return "/" + segments.join("/") } ``` -------------------------------- ### Build Cache Service (TypeScript) Source: https://context7.com/textualize/textualize.io/llms.txt Implements a file-based cache mechanism to persist data across build deployments. It uses MD5 hashing for cache keys and stores data in the `.next/cache` directory. Supports generic types for cached values and handles file read/write operations. ```typescript // src/services/backend/build-cache.ts import { createHash } from "node:crypto" import { promises as fs } from "node:fs" import { join } from "node:path" const cacheFolderPath = ".next/cache" const cacheFileHasher = createHash("md5") export async function get(key: string, defaultValue: T | null = null): Promise { try { const content = await fs.readFile(cacheFilePath(key), "utf8") return JSON.parse(content)["value"] } catch (err) { return defaultValue } } export async function set(key: string, value: T): Promise { const cacheContent = { value, createdAt: new Date().toISOString() } await fs.writeFile( cacheFilePath(key), JSON.stringify(cacheContent) + "\n", "utf8" ) } function cacheFilePath(key: string): string { const hash = cacheFileHasher.copy().update(key).digest("hex") return join(cacheFolderPath, `textualize-cache.${hash}.json`) } // Cache file format: .next/cache/textualize-cache..json // { "value": {...}, "createdAt": "2024-01-15T10:30:00.000Z" } ``` -------------------------------- ### Achieving Precision with Fraction Objects Source: https://github.com/textualize/textualize.io/blob/main/data/blog/2022-08-01---7-things-about-terminals.md This snippet demonstrates how the Fraction class from the fractions module correctly handles arithmetic that would otherwise fail with standard floats. ```python from fractions import Fraction as F F(1, 10) + F(1, 10) + F(1, 10) == F(3, 10) ``` -------------------------------- ### TypeScript Projects Service for Data Retrieval Source: https://context7.com/textualize/textualize.io/llms.txt A backend service in TypeScript that retrieves and transforms project data from a JSON configuration file. It includes caching mechanisms to optimize performance and reduce redundant data fetching. ```typescript // src/services/backend/projects.ts import projectsData from "../../../data/projects.json" import type { ProjectData, ProjectId } from "../../domain" import * as cacheSharedServices from "../shared/cache" import * as githubBackendServices from "./github" export async function projects(): Promise { const cacheKey = "projects" const cachedValue = await cacheSharedServices.get(cacheKey) if (cachedValue) { return cachedValue } const projects = projectsData["projects"].map((rawData) => { return { id: rawData.id as ProjectId, headline: rawData.headline, stars: rawData.stars, desc: rawData.desc, videoUrl: rawData.videoUrl, codeUrl: rawData.code, codeRepoId: githubBackendServices.repoIdFromUrl(rawData.code), docsUrl: rawData.docs ?? null, } }) await cacheSharedServices.set(cacheKey, projects) return projects } // Usage in Next.js page // const projectsData = await projectsBackendServices.projects() ``` -------------------------------- ### Blog Post Markdown Processor Source: https://context7.com/textualize/textualize.io/llms.txt Processes markdown files from a local directory into structured blog post objects. It handles frontmatter parsing, excerpt generation, reading time calculation, and HTML rendering. ```typescript import { promises as fs } from "node:fs"; import fastGlob from "fast-glob"; import matter from "gray-matter"; import readingTime from "reading-time"; import stripTags from "striptags"; import type { BlogPost } from "../../domain"; import { renderMarkdownWithDangerouslyKeptHtml } from "../../helpers/markdown-helpers"; const BLOG_POST_EXCERPT_SEPARATOR = ""; export async function blogPosts(): Promise { const folderPath = "data/blog"; const blogPostsFiles = await fastGlob("*.md", { cwd: folderPath, absolute: true }); const posts = await Promise.all( blogPostsFiles.map((filePath) => blogPostFromMarkdownFilePath(filePath)) ); posts.sort((a, b) => b.date.localeCompare(a.date)); return posts; } async function blogPostFromMarkdownFilePath(filePath: string): Promise { const fileBaseName = basename(filePath, ".md"); const match = fileBaseName.match(/^(\d{4}-\d{2}-\d{2})---([a-z0-9-]+)$/); const [_, date, slug] = match!; const fileContent = await fs.readFile(filePath); const { content, excerpt, data } = matter(fileContent, { excerpt: true, excerpt_separator: BLOG_POST_EXCERPT_SEPARATOR, }); const excerptHtml = renderMarkdownWithDangerouslyKeptHtml(excerpt || "").trim(); const mainContentHtml = renderMarkdownWithDangerouslyKeptHtml(content).trim(); return { slug, title: data.title, date, lastModifiedDate: data.lastModifiedDate || null, author: data.author || "Will McGugan", content: mainContentHtml, excerpt: excerptHtml, readingTime: readingTime(stripTags(mainContentHtml)).minutes, }; } ``` -------------------------------- ### Define Project Data Structure in JSON Source: https://context7.com/textualize/textualize.io/llms.txt This JSON structure defines the schema for project entries, including metadata like ID, headline, star count, and links to source code and documentation. It is used by the static site generator to populate project gallery pages. ```json { "projects": [ { "id": "textual", "headline": "Textual", "stars": "14k", "desc": "Build amazing TUIs with this innovative Python framework", "code": "https://github.com/Textualize/textual", "docs": "https://textual.textualize.io/", "videoUrl": "https://d32lig6y1jobn4.cloudfront.net/textual.mp4" }, { "id": "rich", "headline": "Rich", "stars": "40.3k", "desc": "Beautiful output in the terminal with tables, panels, progress bars...", "code": "https://github.com/Textualize/rich", "docs": "https://rich.readthedocs.io/en/latest/", "videoUrl": "https://d32lig6y1jobn4.cloudfront.net/rich.mp4" } ] } ``` -------------------------------- ### GitHub Repository Statistics Integration Source: https://context7.com/textualize/textualize.io/llms.txt Fetches and caches GitHub repository statistics using a throttled approach to comply with API rate limits. It includes utility functions to parse repository IDs from URLs and batch update star counts for multiple repositories. ```typescript import pThrottle from "p-throttle"; import type { RepoId } from "../../domain"; import { humanizeStargazersCount } from "../../helpers/conversion-helpers"; import * as buildCacheBackendServices from "../backend/build-cache"; export interface GitHubRepoRelatedData { codeUrl: string | null; stars: string | null; } export interface GitHubRepoStatistics { repoId: RepoId; starsCount: number; } export function repoIdFromUrl(repoUrl: string): RepoId { const REPO_URL_REGEX = /^https:\/\/github.com\/(?[^/]+)\/(?[^/]+)\/?$/; const regexMatch = REPO_URL_REGEX.exec(repoUrl ?? ""); if (!regexMatch) { throw new Error(`Not a GitHub repo URL: "${repoUrl}"`); } const { owner, repo } = regexMatch.groups!; return { owner, repo }; } export async function repoStatistics(repoId: RepoId): Promise { const cacheKey = `github-repo-statistics:${repoId.owner}/${repoId.repo}`; const cachedValue = await buildCacheBackendServices.get(cacheKey); if (cachedValue) { return cachedValue; } const resp = await repoStatisticsRawResponse(repoId); if (resp.status !== 200) { throw new Error(`GitHub API failed: status code=${resp.status}`); } const respData = await resp.json(); const result = { repoId, starsCount: respData["stargazers_count"], }; await buildCacheBackendServices.set(cacheKey, result); return result; } export async function attachCurrentStarsCountsToRepositories( repoRelatedDataItems: GitHubRepoRelatedData[] ): Promise { const throttle = pThrottle({ limit: 2, interval: 100, }); const promises = repoRelatedDataItems.map((item) => throttle(async () => { const repoId = repoIdFromUrl(item.codeUrl ?? ""); return repoStatistics(repoId); })() ); const results = await Promise.allSettled(promises); repoRelatedDataItems.forEach((item, index) => { const result = results[index]; if (result.status === "fulfilled") { item.stars = humanizeStargazersCount(result.value.starsCount); } }); } ``` -------------------------------- ### TypeScript Project Data Interfaces Source: https://context7.com/textualize/textualize.io/llms.txt Defines the core data structures for projects, repositories, blog posts, and team members used throughout the Textualize.io application. These interfaces ensure type safety and consistency in data handling. ```typescript // src/domain.ts export interface ProjectData { id: ProjectId headline: string stars: string desc: string videoUrl: string codeUrl: ProjectUrl codeRepoId: RepoId docsUrl: string | null } export interface RepoId { owner: string // e.g., "Textualize" repo: string // e.g., "textual" } export type ProjectId = "textual" | "rich" | "rich-cli" export interface ProjectGalleryItem { projectId: ProjectId id: string title: string image: ImageProperties | null stars: string | null websiteUrl: string | null codeUrl: string | null docsUrl: string | null categories: Category[] description: HtmlString } export interface BlogPost { slug: string title: string date: ISODate lastModifiedDate: ISODate | null author: string content: string excerpt: string readingTime: number } export interface TeamMember { id: string name: string role: string imageUrl: string twitterHandle: string description: HtmlString } ``` -------------------------------- ### Define Team Member Profile in MDX Source: https://context7.com/textualize/textualize.io/llms.txt This MDX file structure combines frontmatter metadata with Markdown content to define team member profiles. The frontmatter includes fields like name, role, and social media handles, which are parsed during the build process. ```markdown --- name: Will McGugan role: "CEO / Founder" imageUrl: /img/about-us/team/will.jpg twitterHandle: willmcgugan --- I am the CEO / Founder of Textualize... ``` -------------------------------- ### Demonstrating Floating Point Precision Issues Source: https://github.com/textualize/textualize.io/blob/main/data/blog/2022-08-01---7-things-about-terminals.md This snippet illustrates the classic floating-point error where the sum of three 0.1 values does not equal 0.3, highlighting the need for higher precision. ```python 0.1 + 0.1 + 0.1 == 0.3 ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.