Update .gitignore and remove untracked files

- Added node_modules/, package-lock.json, discussions/, diagrams/
  and temporary files to .gitignore
- Removed accidentally committed files from git tracking

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
rob 2025-12-31 19:50:13 -04:00
parent 16554c0694
commit c41d2eace2
858 changed files with 8 additions and 162287 deletions

8
.gitignore vendored
View File

@ -35,5 +35,13 @@ ENV/
.DS_Store
Thumbs.db
# Node.js
node_modules/
package-lock.json
# Project specific
*.log
discussions/
diagrams/
*.puml
.tmp_*

File diff suppressed because it is too large Load Diff

View File

@ -1,90 +0,0 @@
@startuml
!define RECTANGLE class
skinparam componentStyle rectangle
skinparam backgroundColor #FEFEFE
package "Landing Page Architecture" {
component "Hero Section" as hero {
[Value Proposition]
[Install Command]
[Primary CTAs]
}
component "Quick Start" as quickstart {
[3-Step Visual Guide]
}
component "Popular Tools" as popular {
[6 Tool Cards]
[API: GET /tools?sort=downloads&limit=6]
}
component "Why SmartTools" as why {
[3 Pillars]
[Easy | Powerful | Community]
}
component "Latest Tutorials" as tutorials {
[3 Tutorial Cards]
[API: GET /content/tutorials?limit=3]
}
component "Contributor Spotlight" as spotlight {
[Monthly Featured Contributor]
}
component "Footer" as footer {
[Navigation Links]
[Donate CTA]
[Social | Legal]
}
component "Ad Slots" as ads {
[Sidebar (desktop only)]
[Optional Footer Banner]
}
database "Registry API" as api
cloud "AdSense" as adsense
hero -down-> quickstart
quickstart -down-> popular
popular -down-> why
why -down-> tutorials
tutorials -down-> spotlight
spotlight -down-> footer
popular ..> api : lazy load
tutorials ..> api : lazy load
ads ..> adsense : async
note right of hero
Critical path:
- FCP < 1.5s
- TTI < 3s
- No layout shift
end note
note right of popular
API response cached:
- 5 min server-side
- ETag/Last-Modified
end note
note right of ads
Load strategy:
- Async after content
- Reserved height
- Fallback if blocked
end note
}
package "Responsive Breakpoints" {
[Mobile <640px] --> [Single column, ads hidden]
[Tablet 640-1024px] --> [2-col optional, footer ads]
[Desktop >1024px] --> [Full layout, sidebar ads]
}
@enduml

View File

@ -1,90 +0,0 @@
@startuml
!theme plain
skinparam backgroundColor #FEFEFE
skinparam shadowing false
title SmartTools Landing Page Architecture
package "Client Browser" {
[User] as User
[HTML/CSS/JS] as Frontend
[Service Worker\n(future)] as SW
}
package "Web Server (Flask)" {
[Landing Page\nController] as LandingCtrl
[Template Engine\n(Jinja)] as Jinja
[Static Assets\nHandler] as StaticAssets
}
package "Registry API" {
[GET /api/v1/stats/summary] as StatsAPI
[GET /api/v1/tools?sort=downloads&limit=6] as ToolsAPI
[GET /api/v1/content/announcements] as AnnouncementsAPI
}
package "Data Layer" {
database "SQLite/PostgreSQL" as DB
[Cache Layer\n(ETag/Last-Modified)] as Cache
}
package "External Services" {
[Google AdSense] as AdSense
[Analytics\n(opt-in)] as Analytics
}
User --> Frontend : "Visit /"
Frontend --> LandingCtrl : "HTTP GET /"
LandingCtrl --> StatsAPI : "Fetch download count,\ntool count"
LandingCtrl --> ToolsAPI : "Fetch popular tools"
LandingCtrl --> AnnouncementsAPI : "Fetch latest announcements\n(optional)"
StatsAPI --> DB : "Read aggregated stats"
ToolsAPI --> DB : "Read tools sorted\nby downloads"
AnnouncementsAPI --> DB : "Read announcements"
DB --> Cache : "Set ETag/Last-Modified"
Cache --> StatsAPI : "Cached response"
Cache --> ToolsAPI : "Cached response"
LandingCtrl --> Jinja : "Render template\nwith data"
Jinja --> Frontend : "Server-rendered HTML"
Frontend --> StaticAssets : "Load CSS, JS, images"
StaticAssets --> Frontend : "Cached assets"
Frontend --> AdSense : "Load ad script\n(after consent)"
Frontend --> Analytics : "Send page view\n(after consent)"
Frontend --> SW : "Cache for offline\n(future PWA)"
note right of LandingCtrl
**Critical Path:**
1. SSR hero section (no API calls)
2. Inline critical CSS
3. Lazy load below-fold content
4. Defer ad scripts
**Performance Targets:**
- FCP: <1.5s
- TTI: <3s
- Page weight: <500KB
end note
note right of Cache
**Caching Strategy:**
- Stats: 5 min TTL
- Tools: 5 min TTL
- Static assets: 24h TTL
- HTML: ETag-based
end note
note bottom of AdSense
**Ad Placement:**
- Optional footer banner only
- Lazy-loaded after content
- Requires user consent
- Fallback: hide on failure
end note
@enduml

View File

@ -1,87 +0,0 @@
@startuml
!theme plain
skinparam componentStyle rectangle
title SmartTools Registry - Resolution & Caching Architecture
actor User
box "Local Environment" #LightBlue
participant "CLI" as CLI
participant "Local\nTools" as Local
participant "Global\nTools" as Global
participant "Cache" as Cache
end box
box "Registry Infrastructure" #LightGreen
participant "API\nServer" as API
database "SQLite\nDB" as DB
participant "Gitea\nRepo" as Repo
end box
User -> CLI: smarttools install summarize
== Resolution Order ==
CLI -> Local: Check ./smarttools/summarize/
Local --> CLI: Not found
CLI -> Global: Check ~/.smarttools/summarize/
Global --> CLI: Not found
CLI -> Cache: Check cached registry index
Cache --> CLI: Found (age: 2 min)
CLI -> API: GET /tools/rob/summarize
API -> DB: Query tool + version
DB --> API: Tool metadata + YAML
API --> CLI: 200 OK + ETag + max-age=300
CLI -> Cache: Update cache entry
CLI -> Global: Write config.yaml
CLI -> Global: Generate wrapper script
CLI --> User: Installed rob/summarize v1.2.0
== Offline Scenario ==
User -> CLI: smarttools install translate
CLI -> Local: Check local
Local --> CLI: Not found
CLI -> Global: Check global
Global --> CLI: Not found
CLI -> Cache: Check cache
Cache --> CLI: Found translate v2.0.0
CLI -> API: GET /tools/rob/translate
API -[#red]-> CLI: Connection timeout
CLI -> Cache: Use stale cache (warn user)
CLI -> Global: Install from cache
CLI --> User: Installed rob/translate v2.0.0\n(warning: from cache, registry unavailable)
== Publishing Flow ==
User -> CLI: smarttools registry publish ./mytool/
CLI -> CLI: Validate YAML schema
CLI -> API: POST /tools (with token)
API -> API: Verify auth token
API -> Repo: Create branch\n(mytool-v1.0.0)
API -> Repo: Commit tool YAML
API -> Repo: Create PR
Repo --> API: PR #42 URL
API --> CLI: 201 Created\n{"pr_url": "..."}
CLI --> User: Tool submitted for review\nPR: https://gitea.brrd.tech/.../pulls/42
== Webhook Sync ==
Repo -> API: POST /webhook/gitea\n(PR merged event + HMAC sig)
API -> API: Verify HMAC signature
API -> Repo: git pull
API -> API: Parse tools/*.yaml
API -> DB: BEGIN TRANSACTION
API -> DB: INSERT/UPDATE tools
API -> DB: REBUILD search_index
API -> DB: COMMIT
API --> Repo: 200 OK
note right of DB
Cache invalidation:
- Clear index.json cache
- Next API call regenerates
- Clients get fresh data
end note
@enduml

View File

@ -1,33 +0,0 @@
@startuml
!theme plain
package "Landing Page" {
package Header {
package "Logo & Nav" {
rectangle "SmartTools Logo" #F0F0F0
rectangle Navigation #F0F0F0
}
}
package "Hero Section" #FFFFFF {
note right: Headline: "Build AI Commands in YAML"\nSubheading: "Unix-style, provider-agnostic, composable"\nCTA: "Browse Registry" (Primary)\nCTA: "Get Started" (Secondary)
}
package "Why SmartTools" #F9FAFB {
note right: 3 Pillars with Icons:\n- Easy to Use\n- Powerful\n- Community
}
package "Featured Tools" #FFFFFF {
note right: Tool Cards (3 columns):\n- Category badge\n- Tool icon/thumbnail\n- Download count\n- Author\n- Quick install command
}
package "Getting Started" #F9FAFB {
note right: Tutorial/Example cards\nLinks to docs, tutorials, examples
}
package Footer #FFFFFF {
note right: Links: About | Donate | Forum | Docs\nOptional footer ad (light background)\nNewsletter signup (subtle)
}
}
note "Design Notes\n---\nColor Palette:\n- Primary: #0052CC (brand blue)\n- Accent: #06B6D4 (teal for secondaries)\n- Background: #F9FAFB (light gray)\n- Cards: #FFFFFF with subtle shadow\n- Ad zone: #FEF3C7 (light yellow background)\n\nMobile: Single column, nav collapses\nTablet: 2 columns featured tools\nDesktop: 3 columns featured tools" as DesignNotes
@enduml

View File

@ -1 +0,0 @@
@startuml smarttools-web-ui-final-review\n!theme plain\nskinparam backgroundColor #F9FAFB\nskinparam noteBkgColor #DBEAFE\nskinparam noteTextColor #1F2937\n\npackage \"WEB_UI.md Design System\" {\n node \"Visual Identity\" {\n card \"Color Palette\n Primary: #6366F1\n Secondary: #06B6D4\n Status: Green/Amber/Red\"\n card \"Typography\n Inter + JetBrains Mono\n 6-tier size scale\n 1.6 line-height body\"\n card \"Spacing\n 8px base grid\n 4px-64px tokens\n Consistent gaps\"\n }\n \n node \"Component System\" {\n card \"Buttons\n Primary, Secondary\n Ghost, Danger\n 44×44px min touch\"\n card \"Cards\n Tool, Tutorial\n Contributor\n Consistent shadow/radius\"\n card \"Forms\n Inputs, Selects\n Validation states\n Error handling\"\n }\n \n node \"Content Architecture\" {\n card \"Tier 1: Ad-Supported\n Landing, Docs\n Tutorials, Blog\n Sidebar ads allowed\"\n card \"Tier 2: Ad-Free Registry\n Tool Browse\n Tool Details\n Zero ad placement\"\n card \"Tier 3: Light Community\n Forum, Contributors\n Announcements\n Optional footer ads\"\n }\n \n node \"Technical Standards\" {\n card \"Accessibility\n WCAG 2.1 AA target\n 4.5:1 contrast\n Keyboard nav\"\n card \"Performance\n <1.5s LCP target\n <500KB total size\n Critical path optimized\"\n card \"SEO\n Server-rendered\n Structured data\n Canonical URLs\"\n }\n}\n\npackage \"Implementation Readiness\" {\n node \"Design Completeness\" {\n card \"✅ Hero spec\n ✅ Featured content\n ✅ Responsive rules\n ✅ Component library\"\n card \"✅ Auth/dashboard\n ✅ Error states\n ✅ Ad enforcement\n ✅ Privacy/consent\"\n card \"✅ Phase 7 checklist\n ✅ API endpoints\n ✅ SEO/technical\n ✅ Launch readiness\"\n }\n}\n\nnote right of \"WEB_UI.md Design System\"\n Complete design system enabling\n consistent frontend development\n across all page types\nend note\n\nnote right of \"Implementation Readiness\"\n Production-ready specification\n with detailed task checklist\n and technical requirements\nend note\n\n@enduml

View File

@ -1,77 +0,0 @@
@startuml
!define ACCENT_COLOR #4A90E2
!define ERROR_COLOR #E85D75
!define SUCCESS_COLOR #5FC98F
!define NEUTRAL_COLOR #8B92A9
skinparam backgroundColor #FFFFFF
skinparam titleFontColor #2C3E50
skinparam arrowColor ACCENT_COLOR
title SmartTools Registry: Visual Design Recommendations
package "Design Strengths" #E8F4F8 {
card "Terminology Table" as str1
card "Clear Hierarchy" as str2
card "Reference Tables" as str3
card "Concrete Examples" as str4
}
package "Enhancement Opportunities" #FFF4E6 {
card "Visual Decision Trees" as enh1
card "ER Diagram Reference" as enh2
card "Sequence Diagrams" as enh3
card "Error Flow Charts" as enh4
card "Consistent Formatting" as enh5
}
package "Critical Flows Needing Visuals" #FFE8E8 {
card "Tool Resolution\n(local → global → registry)" as flow1
card "Version Constraint\nMatching Logic" as flow2
card "Graceful Degradation\nPaths" as flow3
}
package "Implementation Ready" #E8F5E9 {
card "Security Documentation" as imp1
card "API Specification" as imp2
card "Database Schema" as imp3
}
str1 --> str2
str2 --> str3
str3 --> str4
enh1 --> flow1
enh1 --> flow2
enh1 --> flow3
enh2 --> imp3
enh3 --> flow1
enh4 --> flow3
flow1 --> imp1
flow2 --> imp1
flow3 --> imp1
note right of str1
Eliminates ambiguity
from the start
end note
note right of enh1
Would improve clarity
for complex logic
end note
note right of flow1
Critical user journeys
deserve visual representation
end note
note right of imp1
Document is ready for
development with visual
enhancements as complementary
end note
@enduml

View File

@ -1,56 +0,0 @@
@startuml
!theme plain
skinparam backgroundColor #ffffff
skinparam fontFamily monospaced
rectangle "SmartTools Website Structure" {
rectangle "Tier 1: High-Traffic, Ad-Supported" #e8f4f8 {
rectangle "Home/Landing" #c7e9f5
rectangle "Tutorials & Docs" #c7e9f5
rectangle "Blog/Announcements" #c7e9f5
rectangle "Featured Projects" #c7e9f5
}
rectangle "Tier 2: Tool Registry (Ad-Free)" #f0f8e8 {
rectangle "Browse Registry" #d4f1c5
rectangle "Tool Details" #d4f1c5
rectangle "Install Flows" #d4f1c5
}
rectangle "Tier 3: Community (Light Ads)" #f8f4e8 {
rectangle "Forum/Discussions" #f5e6cc
rectangle "Contributors" #f5e6cc
rectangle "Changelog" #f5e6cc
}
}
rectangle "Revenue Streams" {
rectangle "AdSense" #ffe8e8 {
rectangle "Sidebar Ads (300x600)" #ffd4d4
rectangle "Footer Ads (728x90)" #ffd4d4
rectangle "~$50-200/month" #ff9999
}
rectangle "YouTube" #ffe8e8 {
rectangle "Embedded Tutorials" #ffd4d4
rectangle "~$100-500/month" #ff9999
}
rectangle "Community" #ffe8e8 {
rectangle "Donations/Sponsors" #ffd4d4
rectangle "~$250-1500/month" #ff9999
}
}
rectangle "Design Principles" {
rectangle "Visual Hierarchy" #f5f5f5
rectangle "Sparse Ad Placement" #f5f5f5
rectangle "Mobile-First (No Ads <768px)" #f5f5f5
rectangle "Professional Tone" #f5f5f5
}
Tier1 --> AdSense
Tier3 --> Community
DesignPrinciples ..> Tier1
DesignPrinciples ..> Tier2
@enduml

View File

@ -1,97 +0,0 @@
@startuml
!define RECTANGLE rectangle
!define COMPONENT component
skinparam component {
BackgroundColor<<External>> #E6F3FF
BackgroundColor<<Internal>> #F0F0F0
BackgroundColor<<User>> #E8F5E8
BorderColor #333333
ArrowColor #333333
FontSize 12
}
title SmartTools Registry Architecture
package "Users" <<User>> {
actor "CLI User" as cli_user
actor "Web User" as web_user
}
package "Client Interfaces" <<User>> {
component "smarttools CLI" as cli
note right of cli
• registry search
• registry install
• registry publish
• registry browse (TUI)
end note
component "Web UI (future)" as web_ui
note right of web_ui
• Browse tools
• Search
• View tool details
end note
}
component "REGISTRY API SERVER" as api_server <<Internal>> {
rectangle "Flask/FastAPI" as server
note right of server
Hosted at: registry.smarttools.dev
(or gitea.brrd.tech/api/registry)
end note
rectangle "Endpoints" as endpoints
endpoints : GET /tools // list all tools
endpoints : GET /tools/search?q=... // search tools
endpoints : GET /tools/{name} // get tool details
endpoints : GET /tools/{name}/download // download tool config
endpoints : POST /tools // submit new tool (creates PR)
endpoints : GET /categories // list categories
endpoints : GET /stats // download counts, popular tools
rectangle "Internal" as internal
internal : POST /webhook/gitea // receives push/merge events
internal : Sync job // pulls repo, updates DB
}
component "SQLite Database" as database <<Internal>> {
rectangle "Database Schema" as db_schema
db_schema : tools table
db_schema : categories
db_schema : download_stats
db_schema : search_index
}
component "Gitea Repository" as gitea_repo <<External>> {
rectangle "Repository Structure" as repo_structure
repo_structure : gitea.brrd.tech/rob/SmartTools-Registry
repo_structure : /tools/
repo_structure : ├── summarize.yaml
repo_structure : ├── translate.yaml
repo_structure : └── code-review.yaml
repo_structure : /index.json (auto-generated)
repo_structure : /categories.json
}
actor "Tool Publisher" as tool_publisher <<User>> {
note right of tool_publisher
Gitea account required
end note
}
' Connections
cli_user --> cli : uses
web_user --> web_ui : uses
cli --> api_server : HTTPS
web_ui --> api_server : HTTPS
api_server --> database : reads/writes
api_server --> gitea_repo : syncs with
tool_publisher --> gitea_repo : submits PR
gitea_repo --> api_server : webhook events
@enduml

View File

@ -1,61 +0,0 @@
@startuml
!theme plain
skinparam defaultFontName Inter
skinparam backgroundColor #f8f9fa
package "Landing Page Layout" {
component "Hero Section" as hero {
[Value Prop: AI CLI tools for everyone] as value
[Install Snippet (copy button)] as snippet
[Primary CTA: Browse Tools] as primary
[Secondary CTA: View Docs] as secondary
}
component "Value Proposition Grid" as grid {
[Easy to Use\nBeginner-friendly] as easy
[Powerful\nAdvanced features] as powerful
[Community\nCollaboration] as community
}
component "Featured Tools" as tools {
[Tool Card 1] as tool1
[Tool Card 2] as tool2
[Tool Card 3] as tool3
}
note right of tools: 6-8 tools grid
component "Project Showcase" as projects {
[Project Card 1] as proj1
[Project Card 2] as proj2
[Project Card 3] as proj3
}
note right of projects: Real usage examples
component "Getting Started Preview" as getting {
[Tutorial Links] as tutorials
[Quick Start Guide] as guide
}
component "Footer" as footer {
[Newsletter Signup] as newsletter
[Navigation Links] as nav
[Social Links] as social
}
}
hero --> grid
grid --> tools
tools --> projects
projects --> getting
getting --> footer
note bottom of hero
Mobile: Single column
Desktop: Full width hero
end note
note bottom of footer
Optional AdSense banner
Newsletter: Minimal friction
end note
@enduml

View File

@ -1,89 +0,0 @@
@startuml
!theme plain
title SmartTools Registry - Frontend Architecture
package "Web UI (Flask + Jinja + Tailwind)" {
[Landing Page]
[Tool Browser]
[Tool Details]
[Search Results]
[Publisher Dashboard]
[Documentation]
}
package "TUI (Terminal UI)" {
[Registry Browse]
[Tool Search]
[Install Interface]
[Progress Indicators]
}
package "CLI Interface" {
[Publish Flow]
[Install Commands]
[Search Commands]
[Dependency Resolution]
}
package "Client-side State" {
[Search Filters]
[Tool Cache]
[User Preferences]
[Session State]
}
package "Responsive Design" {
[Mobile Viewport]
[Tablet Layout]
[Desktop Experience]
}
' API Connections
[Tool Browser] --> [API Endpoints]
[Search Results] --> [API Endpoints]
[Tool Details] --> [API Endpoints]
[Publisher Dashboard] --> [API Endpoints]
' TUI to API
[Registry Browse] --> [API Endpoints]
[Tool Search] --> [API Endpoints]
[Install Interface] --> [API Endpoints]
' CLI to API
[Publish Flow] --> [API Endpoints]
[Install Commands] --> [API Endpoints]
[Search Commands] --> [API Endpoints]
[Dependency Resolution] --> [API Endpoints]
' Client State Management
[Tool Browser] --> [Tool Cache]
[Search Results] --> [Search Filters]
[Publisher Dashboard] --> [Session State]
' Responsive Breakpoints
[Mobile Viewport] --> [Tool Browser]
[Tablet Layout] --> [Tool Details]
[Desktop Experience] --> [Publisher Dashboard]
note right of [Web UI]
- Server-rendered with Jinja2
- Tailwind CSS for responsive design
- Alpine.js for client interactivity
- SEO-optimized pages
end note
note right of [TUI]
- urwid or python-newt based
- Keyboard navigation (j/k, /, Enter)
- Virtual scrolling for large lists
- Real-time progress feedback
end note
note right of [CLI Interface]
- Progress bars for long operations
- Clear error messages with suggestions
- Token management and secure storage
- Dependency resolution visualization
end note
@enduml

View File

@ -1,71 +0,0 @@
@startuml
!theme plain
skinparam backgroundColor #FFFFFF
skinparam shadowing false
title SmartTools Registry Frontend Architecture
rectangle "Frontend Layer" {
rectangle "Web UI (Flask + Jinja)" as web {
rectangle "Responsive Design" as responsive
rectangle "Progressive Enhancement" as progressive
rectangle "WCAG 2.1 AA" as accessibility
rectangle "SEO Optimized" as seo
}
rectangle "TUI (urwid/python-newt)" as tui {
rectangle "Virtual Scrolling" as virtual
rectangle "Keyboard Navigation" as keyboard
rectangle "Search Interface" as search
rectangle "Progress Indicators" as progress
}
rectangle "CLI Interface" as cli {
rectangle "--dry-run Validation" as dryrun
rectangle "Progress Feedback" as cli_progress
rectangle "Error Handling" as cli_error
rectangle "Offline Support" as offline
}
}
rectangle "Performance Layer" {
rectangle "Client Caching" as client_cache
rectangle "ETag Support" as etag
rectangle "Async Stats" as async_stats
rectangle "Bundle Optimization" as bundle
}
rectangle "User Experience Layer" {
rectangle "Loading States" as loading
rectangle "Error Boundaries" as error_bounds
rectangle "Graceful Degradation" as graceful
rectangle "Screen Reader Support" as screen_reader
}
web --> responsive
web --> progressive
web --> accessibility
web --> seo
tui --> virtual
tui --> keyboard
tui --> search
tui --> progress
cli --> dryrun
cli --> cli_progress
cli --> cli_error
cli --> offline
responsive --> client_cache
progressive --> etag
keyboard --> loading
cli_progress --> async_stats
accessibility --> screen_reader
client_cache --> bundle
etag --> graceful
async_stats --> error_bounds
loading --> screen_reader
@enduml

View File

@ -1,73 +0,0 @@
@startuml
!theme plain
skinparam monochrome true
title SmartTools Web UI - Frontend Architecture & Revenue Strategy
package "Frontend Layers" {
[Landing Page] as LP
[Tool Browse/Search] as TB
[Tool Detail Pages] as TD
[Documentation] as DOC
[Publisher Dashboard] as PD
}
package "Revenue Components" {
[AdSense Integration] as ADS
[Content Marketing] as CONTENT
[Community Features] as COMM
[Premium Features] as PREM
}
package "Technical Stack" {
[Flask + Jinja] as BACKEND
[Tailwind CSS] as CSS
[Alpine.js for Interactivity] as JS
[Service Worker] as SW
}
LP --> ADS : Ad placement
TB --> ADS : Sidebar ads
DOC --> ADS : Between articles
LP --> CONTENT : Featured tools
TB --> CONTENT : Tool showcases
DOC --> CONTENT : Tutorials
TD --> COMM : Tool comments
PD --> COMM : User profiles
ADS --> BACKEND : Ad inventory
CONTENT --> BACKEND : CMS integration
COMM --> BACKEND : Forum backend
PREM --> BACKEND : Subscription logic
BACKEND --> CSS : Server-rendered templates
BACKEND --> JS : Alpine.js sprinkles
SW --> BACKEND : Offline caching
note right of ADS
Strategic placement:
- Search results between
- Tool listing sidebar
- Documentation bottom
- Mobile responsive units
end note
note right of CONTENT
Traffic drivers:
- Video tutorials (YouTube)
- Written tutorials
- Project showcases
- Case studies
end note
note right of COMM
Engagement:
- Tool discussions
- User profiles
- Contributor badges
- Project gallery
end note
@enduml

View File

@ -1,86 +0,0 @@
@startuml
!theme plain
skinparam backgroundColor #FFF
skinparam handwritten false
rectangle "Web UI Architecture" {
rectangle "Tier 1: Ad-Supported Content" as T1 {
[Landing]
[Documentation]
[Tutorials]
[Examples]
[Blog/Announcements]
}
rectangle "Tier 2: Ad-Free Registry" as T2 {
[Tool Browse/Search]
[Tool Details]
[Categories]
[Install Flows]
}
rectangle "Tier 3: Community (Light Ads)" as T3 {
[Forum]
[Contributors]
[Featured Projects]
}
rectangle "Publisher Dashboard (Auth)" as PD {
[Registration/Login]
[Tool Management]
[Token Management]
[Settings]
}
}
cloud "Revenue Streams" {
[AdSense]
[YouTube]
[Donations]
[Featured Listings]
[Premium Tiers]
}
database "Backend" {
[Registry API]
[Content Pages]
[Promotions]
[Featured Projects]
}
T1 --> T2 : "Core Registry"
T2 --> T3 : "Community"
T1 --> PD : "Become Publisher"
T2 --> PD : "Manage Tools"
T1 --> AdSense
T1 --> YouTube
T1 --> Donations
T3 --> Featured Listings
PD --> Premium Tiers
T1 --> [Registry API]
T2 --> [Registry API]
T3 --> [Registry API]
PD --> [Registry API]
note right of T1
Professional documentation
Video tutorials
Community engagement
end note
note right of T2
Ad-free experience
Fast performance
Developer trust
end note
note right of Revenue Streams
Sustainable income
Fund project maintenance
Enable future AI model hosting
Support accessibility goals
end note
@enduml

View File

@ -1,27 +0,0 @@
@startuml
actor "User" as U
participant "SmartTools Website" as W
participant "Payment Gateway" as P
participant "Registry Backend" as B
U -> W : Navigates to "Donate/Contribute" page
W --> U : Displays contribution options (one-time, recurring, tiers)
U -> W : Selects contribution option
W -> W : Validates input (amount, type)
alt Valid Input
W -> P : Initiates payment (e.g., Stripe, PayPal)
P --> U : Prompts for payment details
U -> P : Enters payment details
P --> W : Payment confirmation/failure
alt Payment Success
W -> B : Records contribution
B --> W : Confirmation
W --> U : Displays "Thank You" message & receipt
else Payment Failure
W --> U : Displays error message & retry option
end
else Invalid Input
W --> U : Displays validation error
end
@enduml

View File

@ -1 +0,0 @@
@startuml\nskinparam monochrome true\nskinparam shadowing false\nskinparam handwritten false\n\nactor \"User\" as user\nparticipant \"SmartTools CLI\" as cli\nbox \"Web UI (Flask/Jinja/Tailwind)\" #LightBlue\n participant \"Public Pages (Tier 1)\" as public\n participant \"Registry Pages (Tier 2)\" as registry\n participant \"Community Pages (Tier 3)\" as community\n participant \"Publisher Dashboard\" as dashboard\nend box\nparticipant \"Registry API Server\" as api\nparticipant \"Gitea\" as gitea\nparticipant \"AdSense/Analytics\" as ads\nparticipant \"YouTube\" as youtube\n\nuser -> public: Browse Landing Page (/)\npublic -> ads: Load Ads (if applicable)\npublic -> user: Rendered Landing Page (with ads)\n\nuser -> public: View Docs/Tutorials (/docs/*, /tutorials/*)\npublic -> ads: Load Ads (if applicable)\npublic -> youtube: Embed Video (if present)\npublic -> user: Rendered Content (with ads/videos)\n\nuser -> registry: Browse Tools (/tools, /search)\nregistry -> api: GET /tools, /search\napi --> registry: Tool List/Results\nregistry -> user: Rendered Tool List (NO ADS)\n\nuser -> registry: View Tool Details (/tools/{owner}/{name})\nregistry -> api: GET /tools/{owner}/{name}\napi --> registry: Tool Details\nregistry -> user: Rendered Tool Details (NO ADS)\n\nuser -> community: Visit Forum/Contributors\ncommunity -> ads: Load Light Ads (optional)\ncommunity -> user: Rendered Community Content\n\nuser -> dashboard: Register/Login\ndashboard -> api: POST /register, /login\napi --> dashboard: Auth Token\ndashboard -> user: Access Dashboard\n\nuser -> dashboard: Manage Tools/Tokens\ndashboard -> api: Authenticated API Calls\napi --> dashboard: Data\ndashboard -> user: Rendered Dashboard\n\nuser -> cli: Publish Tool (via CLI)\ncli -> api: POST /tools (authenticated)\napi -> gitea: Create PR\ngitea --> api: PR URL\napi --> cli: PR URL\ncli --> user: PR Confirmation\n\nuser -> public: Donate (/donate)\npublic -> user: Donation Options\n\nuser -> public: View Featured Projects\npublic -> api: GET /featured_projects\napi --> public: Featured Projects Data\npublic -> user: Rendered Featured Projects\n\n@enduml

View File

@ -1,73 +0,0 @@
@startuml
!theme plain
skinparam monochrome true
title SmartTools Web UI - Frontend Architecture & Revenue Strategy
package "Frontend Layers" {
[Landing Page] as LP
[Tool Browse/Search] as TB
[Tool Detail Pages] as TD
[Documentation] as DOC
[Publisher Dashboard] as PD
}
package "Revenue Components" {
[AdSense Integration] as ADS
[Content Marketing] as CONTENT
[Community Features] as COMM
[Premium Features] as PREM
}
package "Technical Stack" {
[Flask + Jinja] as BACKEND
[Tailwind CSS] as CSS
[Alpine.js for Interactivity] as JS
[Service Worker] as SW
}
LP --> ADS : Ad placement
TB --> ADS : Sidebar ads
DOC --> ADS : Between articles
LP --> CONTENT : Featured tools
TB --> CONTENT : Tool showcases
DOC --> CONTENT : Tutorials
TD --> COMM : Tool comments
PD --> COMM : User profiles
ADS --> BACKEND : Ad inventory
CONTENT --> BACKEND : CMS integration
COMM --> BACKEND : Forum backend
PREM --> BACKEND : Subscription logic
BACKEND --> CSS : Server-rendered templates
BACKEND --> JS : Alpine.js sprinkles
SW --> BACKEND : Offline caching
note right of ADS
Strategic placement:
- Search results between
- Tool listing sidebar
- Documentation bottom
- Mobile responsive units
end note
note right of CONTENT
Traffic drivers:
- Video tutorials (YouTube)
- Written tutorials
- Project showcases
- Case studies
end note
note right of COMM
Engagement:
- Tool discussions
- User profiles
- Contributor badges
- Project gallery
end note
@enduml

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

View File

@ -1,72 +0,0 @@
@startuml
!theme reddress-darkblue
title Overall System Diagram
actor "USERS" as Users
actor "Tool Publisher\n(Gitea account required)" as ToolPublisher
rectangle "smarttools CLI" as CLI
note right of CLI
- registry search
- registry install
- registry publish
- registry browse (TUI)
end note
rectangle "Web UI (future)" as WebUI
note right of WebUI
- Browse tools
- Search
- View tool details
end note
component "REGISTRY API SERVER\n(Flask/FastAPI)" as APIServer
note right of APIServer
<b>Host:</b> gitea.brrd.tech/api/registry
--
<b>Endpoints:</b>
- GET /tools
- GET /tools/search?q=...
- GET /tools/{name}
- GET /tools/{name}/download
- POST /tools (creates PR)
- GET /categories
- GET /stats
--
<b>Internal:</b>
- POST /webhook/gitea
- Sync job (pulls repo, updates DB)
end note
database "SQLite Database" as DB
note right of DB
- tools table
- categories
- download_stats
- search_index
end note
component "Gitea Repository\ngitea.brrd.tech/rob/SmartTools-Registry" as GiteaRepo
note right of GiteaRepo
/tools/
- summarize.yaml
- translate.yaml
- code-review.yaml
/index.json (auto-generated)
/categories.json
end note
Users --> CLI
Users --> WebUI
CLI --> APIServer : HTTPS
WebUI --> APIServer : HTTPS
APIServer --> DB : reads/writes
APIServer --> GiteaRepo : syncs with
ToolPublisher --> GiteaRepo : PR for new tools
GiteaRepo --> APIServer : webhook events
@enduml

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 18 KiB

View File

@ -1,49 +0,0 @@
@startuml
title Tool Registry Workflow
== A. Publishing a Tool ==
actor Developer as dev1
participant CLI as cli1
participant "API Server" as api1
participant Gitea as gitea1
dev1 -> cli1 : publish ./tool/
cli1 -> cli1 : validate locally
cli1 -> api1 : POST /tools
api1 -> gitea1 : Create branch
api1 -> gitea1 : Create PR
gitea1 --> api1 : PR URL
api1 --> cli1 : {"pr_url": "..."}
cli1 --> dev1 : "PR created, pending review"
== B. Installing a Tool ==
actor Developer as dev2
participant CLI as cli2
participant "API Server" as api2
participant "Local FS" as fs2
dev2 -> cli2 : install summarize
cli2 -> api2 : GET /tools/summarize
api2 --> cli2 : {config: "yaml..."}
cli2 -> fs2 : write config.yaml
cli2 -> fs2 : generate wrapper script
cli2 --> dev2 : "Installed summarize v1.2.0"
== C. Sync on Merge ==
actor Maintainer as maint
participant Gitea as gitea3
participant "API Server" as api3
participant Database as db3
maint -> gitea3 : Merge PR
gitea3 -> api3 : POST /webhook/gitea
api3 -> gitea3 : git pull
gitea3 --> api3 : (repo contents)
api3 -> api3 : parse tools/
api3 -> db3 : UPDATE tools
api3 -> db3 : rebuild search idx
@enduml

View File

@ -1,41 +0,0 @@
@startuml
title SmartTools Workflow
actor Developer as Dev
participant CLI
participant "API Server" as API
participant Gitea
database "Local FS" as FS
actor Maintainer
box "A. Publishing a Tool"
Dev -> CLI: publish ./tool/
CLI -> CLI: validate locally
CLI -> API: POST /tools
API -> Gitea: Create branch
API -> Gitea: Create PR
Gitea --> API: {"pr_url": "..."}
API --> CLI
CLI --> Dev: "PR created, pending review"
end box
box "B. Installing a Tool"
Dev -> CLI: install summarize
CLI -> API: GET /tools/summarize
API --> CLI: {config: "yaml..."}
CLI -> FS: write config.yaml
CLI -> FS: generate wrapper script
CLI --> Dev: "Installed summarize v1.2.0"
end box
box "C. Sync on Merge (keeping API in sync with repo)"
Maintainer -> Gitea: Merge PR
Gitea -> API: POST /webhook/gitea
API -> Gitea: git pull
Gitea --> API: (repo contents)
API -> API: parse tools/
API -> Database: UPDATE tools
API -> Database: rebuild search idx
end box
@enduml

View File

@ -1,190 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 1600" width="1200" height="1600">
<title>SmartTools Landing Page Mockup - Improved</title>
<!-- Page Background -->
<rect id="page-background" x="0" y="0" width="1200" height="1600" fill="#F9FAFB"/>
<!-- Header -->
<rect id="header-bar" x="0" y="0" width="1200" height="60" fill="#2C3E50"/>
<text id="site-logo" x="50" y="38" font-family="Arial, sans-serif" font-size="24" fill="#fff" font-weight="bold">SmartTools</text>
<g id="nav-links">
<text x="700" y="38" font-family="Arial, sans-serif" font-size="16" fill="#fff">Docs</text>
<text x="770" y="38" font-family="Arial, sans-serif" font-size="16" fill="#fff">Tutorials</text>
<text x="860" y="38" font-family="Arial, sans-serif" font-size="16" fill="#fff">Registry</text>
<text x="940" y="38" font-family="Arial, sans-serif" font-size="16" fill="#fff">Community</text>
<text x="1030" y="38" font-family="Arial, sans-serif" font-size="16" fill="#fff">About</text>
<text x="1090" y="38" font-family="Arial, sans-serif" font-size="16" fill="#fff">Donate</text>
<!-- Search Icon -->
<circle cx="1150" cy="30" r="10" fill="none" stroke="#fff" stroke-width="2"/>
<line x1="1157" y1="37" x2="1165" y2="45" stroke="#fff" stroke-width="2" stroke-linecap="round"/>
</g>
<!-- Main Content Area -->
<g id="main-content">
<!-- Hero Section -->
<rect id="hero-section" x="50" y="90" width="1100" height="280" fill="#FFFFFF" rx="10" ry="10" stroke="#E0E0E0" stroke-width="1"/>
<text x="100" y="150" font-family="Arial, sans-serif" font-size="36" fill="#333" font-weight="bold">Build Custom AI Commands in YAML</text>
<text x="100" y="190" font-family="Arial, sans-serif" font-size="18" fill="#666">Test</text>
<text x="100" y="215" font-family="Arial, sans-serif" font-size="18" fill="#666">Provider-agnostic and composable for ultimate flexibility.</text>
<!-- Install Snippet -->
<rect x="100" y="245" width="450" height="40" fill="#E0E0E0" rx="5" ry="5"/>
<text x="110" y="270" font-family="monospace" font-size="14" fill="#333">$ pip install smarttools &amp;&amp; smarttools init</text>
<!-- CTA Buttons -->
<rect x="100" y="300" width="180" height="45" fill="#6366F1" rx="5" ry="5"/>
<text x="120" y="328" font-family="Arial, sans-serif" font-size="16" fill="#fff" font-weight="bold">Get Started</text>
<rect x="300" y="300" width="180" height="45" fill="none" stroke="#06B6D4" stroke-width="2" rx="5" ry="5"/>
<text x="320" y="328" font-family="Arial, sans-serif" font-size="16" fill="#06B6D4" font-weight="bold">View Tutorials</text>
<!-- Why SmartTools Section (Three Pillars) -->
<text x="50" y="420" font-family="Arial, sans-serif" font-size="24" fill="#333" font-weight="bold">Why SmartTools?</text>
<g id="three-pillars">
<!-- Pillar 1: Easy to Use -->
<rect x="50" y="450" width="350" height="150" fill="#FFFFFF" stroke="#E0E0E0" stroke-width="1" rx="5" ry="5" filter="url(#shadow)"/>
<circle cx="100" cy="490" r="20" fill="#6366F1"/>
<text x="90" y="498" font-family="Arial, sans-serif" font-size="18" fill="#fff" font-weight="bold"></text>
<text x="140" y="490" font-family="Arial, sans-serif" font-size="18" fill="#333" font-weight="bold">Easy to Use</text>
<text x="60" y="520" font-family="Arial, sans-serif" font-size="14" fill="#666">Simple YAML configuration for quick setup.</text>
<!-- Pillar 2: Powerful -->
<rect x="425" y="450" width="350" height="150" fill="#FFFFFF" stroke="#E0E0E0" stroke-width="1" rx="5" ry="5" filter="url(#shadow)"/>
<circle cx="475" cy="490" r="20" fill="#06B6D4"/>
<text x="465" y="498" font-family="Arial, sans-serif" font-size="18" fill="#fff" font-weight="bold"></text>
<text x="515" y="490" font-family="Arial, sans-serif" font-size="18" fill="#333" font-weight="bold">Powerful</text>
<text x="435" y="520" font-family="Arial, sans-serif" font-size="14" fill="#666">Leverage any AI provider, compose complex workflows.</text>
<!-- Pillar 3: Community -->
<rect x="800" y="450" width="350" height="150" fill="#FFFFFF" stroke="#E0E0E0" stroke-width="1" rx="5" ry="5" filter="url(#shadow)"/>
<circle cx="850" cy="490" r="20" fill="#6366F1"/>
<text x="840" y="498" font-family="Arial, sans-serif" font-size="18" fill="#fff" font-weight="bold">👥</text>
<text x="890" y="490" font-family="Arial, sans-serif" font-size="18" fill="#333" font-weight="bold">Community</text>
<text x="810" y="520" font-family="Arial, sans-serif" font-size="14" fill="#666">Share, discover, and contribute to a growing ecosystem.</text>
</g>
<!-- Featured Tools & Projects -->
<text x="50" y="650" font-family="Arial, sans-serif" font-size="24" fill="#333" font-weight="bold">Featured Tools &amp; Projects</text>
<g id="featured-grid">
<!-- Tool Card 1 -->
<rect x="50" y="680" width="350" height="180" fill="#FFFFFF" stroke="#E0E0E0" stroke-width="1" rx="5" ry="5" filter="url(#shadow)"/>
<rect x="340" y="690" width="50" height="20" fill="#06B6D4" rx="3" ry="3"/>
<text x="345" y="705" font-family="Arial, sans-serif" font-size="12" fill="#fff">Category</text>
<circle cx="70" cy="700" r="10" fill="#6366F1"/>
<text x="90" y="705" font-family="Arial, sans-serif" font-size="18" fill="#333" font-weight="bold">Tool Title 1</text>
<text x="60" y="730" font-family="Arial, sans-serif" font-size="14" fill="#666">Short description of the tool.</text>
<text x="60" y="750" font-family="Arial, sans-serif" font-size="12" fill="#888">Author: John Doe</text>
<text x="60" y="770" font-family="Arial, sans-serif" font-size="12" fill="#888">Downloads: 1.2K</text>
<rect x="60" y="790" width="150" height="25" fill="#E0E0E0" rx="3" ry="3"/>
<text x="65" y="807" font-family="monospace" font-size="12" fill="#333">smarttools run tool1</text>
<!-- Tool Card 2 -->
<rect x="425" y="680" width="350" height="180" fill="#FFFFFF" stroke="#E0E0E0" stroke-width="1" rx="5" ry="5" filter="url(#shadow)"/>
<rect x="715" y="690" width="50" height="20" fill="#06B6D4" rx="3" ry="3"/>
<text x="720" y="705" font-family="Arial, sans-serif" font-size="12" fill="#fff">Category</text>
<circle cx="445" cy="700" r="10" fill="#6366F1"/>
<text x="465" y="705" font-family="Arial, sans-serif" font-size="18" fill="#333" font-weight="bold">Tool Title 2</text>
<text x="435" y="730" font-family="Arial, sans-serif" font-size="14" fill="#666">Short description of the tool.</text>
<text x="435" y="750" font-family="Arial, sans-serif" font-size="12" fill="#888">Author: Jane Smith</text>
<text x="435" y="770" font-family="Arial, sans-serif" font-size="12" fill="#888">Downloads: 800</text>
<rect x="435" y="790" width="150" height="25" fill="#E0E0E0" rx="3" ry="3"/>
<text x="440" y="807" font-family="monospace" font-size="12" fill="#333">smarttools run tool2</text>
<!-- Tool Card 3 -->
<rect x="800" y="680" width="350" height="180" fill="#FFFFFF" stroke="#E0E0E0" stroke-width="1" rx="5" ry="5" filter="url(#shadow)"/>
<rect x="1090" y="690" width="50" height="20" fill="#06B6D4" rx="3" ry="3"/>
<text x="1095" y="705" font-family="Arial, sans-serif" font-size="12" fill="#fff">Category</text>
<circle cx="820" cy="700" r="10" fill="#6366F1"/>
<text x="840" y="705" font-family="Arial, sans-serif" font-size="18" fill="#333" font-weight="bold">Tool Title 3</text>
<text x="810" y="730" font-family="Arial, sans-serif" font-size="14" fill="#666">Short description of the tool.</text>
<text x="810" y="750" font-family="Arial, sans-serif" font-size="12" fill="#888">Author: Bob Johnson</text>
<text x="810" y="770" font-family="Arial, sans-serif" font-size="12" fill="#888">Downloads: 2.5K</text>
<rect x="810" y="790" width="150" height="25" fill="#E0E0E0" rx="3" ry="3"/>
<text x="815" y="807" font-family="monospace" font-size="12" fill="#333">smarttools run tool3</text>
<!-- Tool Card 4 -->
<rect x="50" y="880" width="350" height="180" fill="#FFFFFF" stroke="#E0E0E0" stroke-width="1" rx="5" ry="5" filter="url(#shadow)"/>
<rect x="340" y="890" width="50" height="20" fill="#06B6D4" rx="3" ry="3"/>
<text x="345" y="905" font-family="Arial, sans-serif" font-size="12" fill="#fff">Category</text>
<circle cx="70" cy="900" r="10" fill="#6366F1"/>
<text x="90" y="905" font-family="Arial, sans-serif" font-size="18" fill="#333" font-weight="bold">Tool Title 4</text>
<text x="60" y="930" font-family="Arial, sans-serif" font-size="14" fill="#666">Short description of the tool.</text>
<text x="60" y="950" font-family="Arial, sans-serif" font-size="12" fill="#888">Author: Alice Brown</text>
<text x="60" y="970" font-family="Arial, sans-serif" font-size="12" fill="#888">Downloads: 500</text>
<rect x="60" y="990" width="150" height="25" fill="#E0E0E0" rx="3" ry="3"/>
<text x="65" y="1007" font-family="monospace" font-size="12" fill="#333">smarttools run tool4</text>
<!-- Tool Card 5 -->
<rect x="425" y="880" width="350" height="180" fill="#FFFFFF" stroke="#E0E0E0" stroke-width="1" rx="5" ry="5" filter="url(#shadow)"/>
<rect x="715" y="890" width="50" height="20" fill="#06B6D4" rx="3" ry="3"/>
<text x="720" y="905" font-family="Arial, sans-serif" font-size="12" fill="#fff">Category</text>
<circle cx="445" cy="900" r="10" fill="#6366F1"/>
<text x="465" y="905" font-family="Arial, sans-serif" font-size="18" fill="#333" font-weight="bold">Tool Title 5</text>
<text x="435" y="930" font-family="Arial, sans-serif" font-size="14" fill="#666">Short description of the tool.</text>
<text x="435" y="950" font-family="Arial, sans-serif" font-size="12" fill="#888">Author: Charlie Green</text>
<text x="435" y="970" font-family="Arial, sans-serif" font-size="12" fill="#888">Downloads: 1.8K</text>
<rect x="435" y="990" width="150" height="25" fill="#E0E0E0" rx="3" ry="3"/>
<text x="440" y="1007" font-family="monospace" font-size="12" fill="#333">smarttools run tool5</text>
<!-- Tool Card 6 -->
<rect x="800" y="880" width="350" height="180" fill="#FFFFFF" stroke="#E0E0E0" stroke-width="1" rx="5" ry="5" filter="url(#shadow)"/>
<rect x="1090" y="890" width="50" height="20" fill="#06B6D4" rx="3" ry="3"/>
<text x="1095" y="905" font-family="Arial, sans-serif" font-size="12" fill="#fff">Category</text>
<circle cx="820" cy="900" r="10" fill="#6366F1"/>
<text x="840" y="905" font-family="Arial, sans-serif" font-size="18" fill="#333" font-weight="bold">Tool Title 6</text>
<text x="810" y="930" font-family="Arial, sans-serif" font-size="14" fill="#666">Short description of the tool.</text>
<text x="810" y="950" font-family="Arial, sans-serif" font-size="12" fill="#888">Author: David White</text>
<text x="810" y="970" font-family="Arial, sans-serif" font-size="12" fill="#888">Downloads: 900</text>
<rect x="810" y="990" width="150" height="25" fill="#E0E0E0" rx="3" ry="3"/>
<text x="815" y="1007" font-family="monospace" font-size="12" fill="#333">smarttools run tool6</text>
</g>
<!-- Getting Started Section -->
<text x="50" y="1110" font-family="Arial, sans-serif" font-size="24" fill="#333" font-weight="bold">Getting Started</text>
<g id="getting-started-cards">
<rect x="50" y="1140" width="350" height="120" fill="#FFFFFF" stroke="#E0E0E0" stroke-width="1" rx="5" ry="5" filter="url(#shadow)"/>
<text x="60" y="1165" font-family="Arial, sans-serif" font-size="18" fill="#333" font-weight="bold">Tutorial 1: Basic Setup</text>
<text x="60" y="1190" font-family="Arial, sans-serif" font-size="14" fill="#666">Learn how to install and configure SmartTools.</text>
<rect x="60" y="1205" width="100" height="25" fill="#6366F1" rx="3" ry="3"/>
<text x="65" y="1222" font-family="Arial, sans-serif" font-size="12" fill="#fff">Read More</text>
<rect x="425" y="1140" width="350" height="120" fill="#FFFFFF" stroke="#E0E0E0" stroke-width="1" rx="5" ry="5" filter="url(#shadow)"/>
<text x="435" y="1165" font-family="Arial, sans-serif" font-size="18" fill="#333" font-weight="bold">Tutorial 2: Your First Tool</text>
<text x="435" y="1190" font-family="Arial, sans-serif" font-size="14" fill="#666">Create a simple AI command in YAML.</text>
<rect x="435" y="1205" width="100" height="25" fill="#6366F1" rx="3" ry="3"/>
<text x="440" y="1222" font-family="Arial, sans-serif" font-size="12" fill="#fff">Read More</text>
<!-- Tutorial 3: Advanced Workflows -->
<rect x="800" y="1140" width="350" height="120" fill="#FFFFFF" stroke="#E0E0E0" stroke-width="1" rx="5" ry="5" filter="url(#shadow)"/>
<text x="810" y="1165" font-family="Arial, sans-serif" font-size="18" fill="#333" font-weight="bold">Tutorial 3: Advanced Workflows</text>
<text x="810" y="1190" font-family="Arial, sans-serif" font-size="14" fill="#666">Combine multiple tools for complex tasks.</text>
<rect x="810" y="1205" width="100" height="25" fill="#6366F1" rx="3" ry="3"/>
<text x="815" y="1222" font-family="Arial, sans-serif" font-size="12" fill="#fff">Read More</text>
</g>
<!-- Featured Contributor Section -->
<text x="50" y="1310" font-family="Arial, sans-serif" font-size="24" fill="#333" font-weight="bold">Featured Contributor</text>
<rect x="50" y="1340" width="1100" height="100" fill="#FFFFFF" stroke="#E0E0E0" stroke-width="1" rx="5" ry="5" filter="url(#shadow)"/>
<circle cx="100" cy="1390" r="30" fill="#D0D0D0"/>
<text x="100" y="1398" text-anchor="middle" font-family="Arial, sans-serif" font-size="24" fill="#666">👤</text>
<text x="150" y="1380" font-family="Arial, sans-serif" font-size="20" fill="#333" font-weight="bold">Alice Wonderland</text>
<text x="150" y="1405" font-family="Arial, sans-serif" font-size="16" fill="#666">Creator of the "Image Captioning" tool and active community member.</text>
<rect x="150" y="1420" width="150" height="25" fill="#06B6D4" rx="3" ry="3"/>
<text x="155" y="1437" font-family="Arial, sans-serif" font-size="12" fill="#fff">View Profile</text>
</g>
<!-- Footer Ad Banner -->
<rect id="footer-ad" x="0" y="1520" width="1200" height="80" fill="#DBEAFE"/>
<text x="600" y="1565" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" fill="#666">Advertisement: Support SmartTools Development</text>
<!-- Define a subtle shadow filter -->
<defs>
<filter id="shadow" x="-50%" y="-50%" width="200%" height="200%">
<feOffset result="offOut" in="SourceAlpha" dx="0" dy="2"/>
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="3"/>
<feBlend in="SourceGraphic" in2="blurOut" mode="normal"/>
</filter>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,63 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1600" viewBox="0 0 1200 1600">
<rect width="1200" height="1600" fill="#F9FAFB" />
<!-- Header -->
<rect x="80" y="40" width="1040" height="70" rx="10" fill="#FFFFFF" stroke="#E5E7EB" />
<text x="110" y="82" font-family="Arial" font-size="20" fill="#111827">SmartTools</text>
<text x="520" y="82" font-family="Arial" font-size="14" fill="#6B7280">Docs Tutorials Registry Community About Donate</text>
<rect x="980" y="55" width="120" height="40" rx="8" fill="#1D4ED8" />
<text x="1000" y="80" font-family="Arial" font-size="14" fill="#FFFFFF">Get Started</text>
<!-- Hero -->
<rect x="80" y="140" width="1040" height="280" rx="16" fill="#FFFFFF" stroke="#E5E7EB" />
<text x="120" y="190" font-family="Arial" font-size="28" fill="#111827">Build AI CLI tools in YAML. Compose them like Unix commands.</text>
<text x="120" y="220" font-family="Arial" font-size="16" fill="#6B7280">Provider-agnostic, shareable, and built for collaboration.</text>
<rect x="120" y="240" width="520" height="60" rx="8" fill="#0F172A" />
<text x="140" y="275" font-family="Courier New" font-size="16" fill="#E5E7EB">pip install -e . &amp;&amp; smarttools registry browse</text>
<rect x="120" y="320" width="170" height="44" rx="8" fill="#1D4ED8" />
<text x="142" y="348" font-family="Arial" font-size="14" fill="#FFFFFF">Browse Registry</text>
<rect x="310" y="320" width="170" height="44" rx="8" fill="#E5E7EB" />
<text x="335" y="348" font-family="Arial" font-size="14" fill="#111827">View Tutorials</text>
<!-- Pillars -->
<rect x="80" y="450" width="1040" height="170" rx="16" fill="#FFFFFF" stroke="#E5E7EB" />
<rect x="110" y="480" width="320" height="110" rx="12" fill="#F3F4F6" />
<rect x="440" y="480" width="320" height="110" rx="12" fill="#F3F4F6" />
<rect x="770" y="480" width="320" height="110" rx="12" fill="#F3F4F6" />
<text x="130" y="515" font-family="Arial" font-size="14" fill="#111827">Easy to Use</text>
<text x="460" y="515" font-family="Arial" font-size="14" fill="#111827">Powerful</text>
<text x="790" y="515" font-family="Arial" font-size="14" fill="#111827">Community</text>
<!-- Featured tools -->
<text x="80" y="670" font-family="Arial" font-size="18" fill="#111827">Featured Tools</text>
<rect x="80" y="690" width="1040" height="260" rx="16" fill="#FFFFFF" stroke="#E5E7EB" />
<!-- Cards -->
<rect x="110" y="720" width="300" height="200" rx="12" fill="#F9FAFB" stroke="#E5E7EB" />
<rect x="450" y="720" width="300" height="200" rx="12" fill="#F9FAFB" stroke="#E5E7EB" />
<rect x="790" y="720" width="300" height="200" rx="12" fill="#F9FAFB" stroke="#E5E7EB" />
<text x="130" y="755" font-family="Arial" font-size="13" fill="#111827">official/summarize</text>
<text x="130" y="780" font-family="Arial" font-size="12" fill="#6B7280">text-processing</text>
<text x="130" y="805" font-family="Arial" font-size="12" fill="#6B7280">⬇ 1,240</text>
<!-- Getting started -->
<text x="80" y="990" font-family="Arial" font-size="18" fill="#111827">Getting Started</text>
<rect x="80" y="1010" width="1040" height="170" rx="16" fill="#FFFFFF" stroke="#E5E7EB" />
<rect x="110" y="1040" width="320" height="110" rx="12" fill="#F3F4F6" />
<rect x="440" y="1040" width="320" height="110" rx="12" fill="#F3F4F6" />
<rect x="770" y="1040" width="320" height="110" rx="12" fill="#F3F4F6" />
<!-- Projects + Contributors -->
<text x="80" y="1220" font-family="Arial" font-size="18" fill="#111827">Featured Projects &amp; Contributors</text>
<rect x="80" y="1240" width="1040" height="190" rx="16" fill="#FFFFFF" stroke="#E5E7EB" />
<rect x="110" y="1270" width="500" height="130" rx="12" fill="#F3F4F6" />
<rect x="640" y="1270" width="450" height="130" rx="12" fill="#F3F4F6" />
<!-- Footer / Sponsored -->
<rect x="80" y="1460" width="1040" height="80" rx="10" fill="#FEF3C7" stroke="#FDE68A" />
<text x="100" y="1505" font-family="Arial" font-size="12" fill="#92400E">Sponsored</text>
<text x="180" y="1505" font-family="Arial" font-size="12" fill="#92400E">Ad slot (optional, footer only)</text>
</svg>

Before

Width:  |  Height:  |  Size: 4.1 KiB

File diff suppressed because one or more lines are too long

View File

@ -1,100 +0,0 @@
@startuml
!define RECTANGLE rectangle
!define COMPONENT component
skinparam component {
BackgroundColor<<External>> #E6F3FF
BackgroundColor<<Internal>> #F0F0F0
BackgroundColor<<User>> #E8F5E8
BorderColor #333333
ArrowColor #333333
FontSize 12
}
title SmartTools Registry Architecture
package "Users" <<User>> {
actor "CLI User" as cli_user
actor "Web User" as web_user
actor "Tool Publisher" as tool_publisher
}
note right of tool_publisher
Gitea account required
end note
package "Client Interfaces" <<User>> {
component "smarttools CLI" as cli
component "Web UI (future)" as web_ui
}
note right of cli
• registry search
• registry install
• registry publish
• registry browse (TUI)
end note
note right of web_ui
• Browse tools
• Search
• View tool details
end note
package "REGISTRY API SERVER" <<Internal>> {
component "Flask/FastAPI" as server
component "Endpoints" as endpoints
component "Internal" as internal
}
note right of server
Hosted at: registry.smarttools.dev
(or gitea.brrd.tech/api/registry)
end note
endpoints : GET /tools
endpoints : GET /tools/search?q=...
endpoints : GET /tools/{name}
endpoints : GET /tools/{name}/download
endpoints : POST /tools
endpoints : GET /categories
endpoints : GET /stats
internal : POST /webhook/gitea
internal : Sync job
component "SQLite Database" as database <<Internal>> {
component "Database Schema" as db_schema
}
db_schema : tools table
db_schema : categories
db_schema : download_stats
db_schema : search_index
component "Gitea Repository" as gitea_repo <<External>> {
component "Repository Structure" as repo_structure
}
repo_structure : gitea.brrd.tech/rob/SmartTools-Registry
repo_structure : /tools/
repo_structure : ├── summarize.yaml
repo_structure : ├── translate.yaml
repo_structure : └── code-review.yaml
repo_structure : /index.json (auto-generated)
repo_structure : /categories.json
' Connections
cli_user --> cli : uses
web_user --> web_ui : uses
cli --> api_server : HTTPS
web_ui --> api_server : HTTPS
api_server --> database : reads/writes
api_server --> gitea_repo : syncs with
tool_publisher --> gitea_repo : submits PR
gitea_repo --> api_server : webhook events
@enduml

1
node_modules/.bin/cssesc generated vendored
View File

@ -1 +0,0 @@
../cssesc/bin/cssesc

1
node_modules/.bin/jiti generated vendored
View File

@ -1 +0,0 @@
../jiti/bin/jiti.js

1
node_modules/.bin/nanoid generated vendored
View File

@ -1 +0,0 @@
../nanoid/bin/nanoid.cjs

1
node_modules/.bin/resolve generated vendored
View File

@ -1 +0,0 @@
../resolve/bin/resolve

1
node_modules/.bin/sucrase generated vendored
View File

@ -1 +0,0 @@
../sucrase/bin/sucrase

1
node_modules/.bin/sucrase-node generated vendored
View File

@ -1 +0,0 @@
../sucrase/bin/sucrase-node

1
node_modules/.bin/tailwind generated vendored
View File

@ -1 +0,0 @@
../tailwindcss/lib/cli.js

1
node_modules/.bin/tailwindcss generated vendored
View File

@ -1 +0,0 @@
../tailwindcss/lib/cli.js

994
node_modules/.package-lock.json generated vendored
View File

@ -1,994 +0,0 @@
{
"name": "smarttools-web",
"lockfileVersion": 3,
"requires": true,
"packages": {
"node_modules/@alloc/quick-lru": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
"integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.13",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0",
"@jridgewell/trace-mapping": "^0.3.24"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
"dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.31",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "2.0.5",
"run-parallel": "^1.1.9"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/@nodelib/fs.stat": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 8"
}
},
"node_modules/@nodelib/fs.walk": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@nodelib/fs.scandir": "2.1.5",
"fastq": "^1.6.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/any-promise": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
"integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
"dev": true,
"license": "MIT"
},
"node_modules/anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"dev": true,
"license": "ISC",
"dependencies": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/arg": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
"dev": true,
"license": "MIT"
},
"node_modules/binary-extensions": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/braces": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"license": "MIT",
"dependencies": {
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/camelcase-css": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
"integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 6"
}
},
"node_modules/chokidar": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"dev": true,
"license": "MIT",
"dependencies": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.6.0"
},
"engines": {
"node": ">= 8.10.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
}
},
"node_modules/chokidar/node_modules/glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"license": "ISC",
"dependencies": {
"is-glob": "^4.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/commander": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 6"
}
},
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"dev": true,
"license": "MIT",
"bin": {
"cssesc": "bin/cssesc"
},
"engines": {
"node": ">=4"
}
},
"node_modules/didyoumean": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
"integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/dlv": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
"dev": true,
"license": "MIT"
},
"node_modules/fast-glob": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3",
"glob-parent": "^5.1.2",
"merge2": "^1.3.0",
"micromatch": "^4.0.8"
},
"engines": {
"node": ">=8.6.0"
}
},
"node_modules/fast-glob/node_modules/glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"license": "ISC",
"dependencies": {
"is-glob": "^4.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/fastq": {
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
"integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
"dev": true,
"license": "ISC",
"dependencies": {
"reusify": "^1.0.4"
}
},
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/glob-parent": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
"dev": true,
"license": "ISC",
"dependencies": {
"is-glob": "^4.0.3"
},
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
"license": "MIT",
"dependencies": {
"binary-extensions": "^2.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/is-core-module": {
"version": "2.16.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
"integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
"dev": true,
"license": "MIT",
"dependencies": {
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-extglob": "^2.1.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
}
},
"node_modules/jiti": {
"version": "1.21.7",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
"dev": true,
"license": "MIT",
"bin": {
"jiti": "bin/jiti.js"
}
},
"node_modules/lilconfig": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
"integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/antonk52"
}
},
"node_modules/lines-and-columns": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true,
"license": "MIT"
},
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 8"
}
},
"node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
"license": "MIT",
"dependencies": {
"braces": "^3.0.3",
"picomatch": "^2.3.1"
},
"engines": {
"node": ">=8.6"
}
},
"node_modules/mz": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
"integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"any-promise": "^1.0.0",
"object-assign": "^4.0.1",
"thenify-all": "^1.0.0"
}
},
"node_modules/nanoid": {
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/object-hash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 6"
}
},
"node_modules/path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true,
"license": "MIT"
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"dev": true,
"license": "ISC"
},
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/pirates": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
"integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 6"
}
},
"node_modules/postcss": {
"version": "8.5.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
"dev": true,
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/postcss-import": {
"version": "15.1.0",
"resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
"integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
"dev": true,
"license": "MIT",
"dependencies": {
"postcss-value-parser": "^4.0.0",
"read-cache": "^1.0.0",
"resolve": "^1.1.7"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"postcss": "^8.0.0"
}
},
"node_modules/postcss-js": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz",
"integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==",
"dev": true,
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"dependencies": {
"camelcase-css": "^2.0.1"
},
"engines": {
"node": "^12 || ^14 || >= 16"
},
"peerDependencies": {
"postcss": "^8.4.21"
}
},
"node_modules/postcss-load-config": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
"integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==",
"dev": true,
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"dependencies": {
"lilconfig": "^3.1.1"
},
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"jiti": ">=1.21.0",
"postcss": ">=8.0.9",
"tsx": "^4.8.1",
"yaml": "^2.4.2"
},
"peerDependenciesMeta": {
"jiti": {
"optional": true
},
"postcss": {
"optional": true
},
"tsx": {
"optional": true
},
"yaml": {
"optional": true
}
}
},
"node_modules/postcss-nested": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
"integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
"dev": true,
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"dependencies": {
"postcss-selector-parser": "^6.1.1"
},
"engines": {
"node": ">=12.0"
},
"peerDependencies": {
"postcss": "^8.2.14"
}
},
"node_modules/postcss-selector-parser": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
"dev": true,
"license": "MIT",
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
},
"engines": {
"node": ">=4"
}
},
"node_modules/postcss-value-parser": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"dev": true,
"license": "MIT"
},
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT"
},
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
"integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
"dev": true,
"license": "MIT",
"dependencies": {
"pify": "^2.3.0"
}
},
"node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true,
"license": "MIT",
"dependencies": {
"picomatch": "^2.2.1"
},
"engines": {
"node": ">=8.10.0"
}
},
"node_modules/resolve": {
"version": "1.22.11",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
"integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-core-module": "^2.16.1",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
"bin": {
"resolve": "bin/resolve"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/reusify": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
"integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
"dev": true,
"license": "MIT",
"engines": {
"iojs": ">=1.0.0",
"node": ">=0.10.0"
}
},
"node_modules/run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT",
"dependencies": {
"queue-microtask": "^1.2.2"
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/sucrase": {
"version": "3.35.1",
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz",
"integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.2",
"commander": "^4.0.0",
"lines-and-columns": "^1.1.6",
"mz": "^2.7.0",
"pirates": "^4.0.1",
"tinyglobby": "^0.2.11",
"ts-interface-checker": "^0.1.9"
},
"bin": {
"sucrase": "bin/sucrase",
"sucrase-node": "bin/sucrase-node"
},
"engines": {
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/tailwindcss": {
"version": "3.4.19",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz",
"integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
"arg": "^5.0.2",
"chokidar": "^3.6.0",
"didyoumean": "^1.2.2",
"dlv": "^1.1.3",
"fast-glob": "^3.3.2",
"glob-parent": "^6.0.2",
"is-glob": "^4.0.3",
"jiti": "^1.21.7",
"lilconfig": "^3.1.3",
"micromatch": "^4.0.8",
"normalize-path": "^3.0.0",
"object-hash": "^3.0.0",
"picocolors": "^1.1.1",
"postcss": "^8.4.47",
"postcss-import": "^15.1.0",
"postcss-js": "^4.0.1",
"postcss-load-config": "^4.0.2 || ^5.0 || ^6.0",
"postcss-nested": "^6.2.0",
"postcss-selector-parser": "^6.1.2",
"resolve": "^1.22.8",
"sucrase": "^3.35.0"
},
"bin": {
"tailwind": "lib/cli.js",
"tailwindcss": "lib/cli.js"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/thenify": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
"integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
"dev": true,
"license": "MIT",
"dependencies": {
"any-promise": "^1.0.0"
}
},
"node_modules/thenify-all": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
"integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
"dev": true,
"license": "MIT",
"dependencies": {
"thenify": ">= 3.1.0 < 4"
},
"engines": {
"node": ">=0.8"
}
},
"node_modules/tinyglobby": {
"version": "0.2.15",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
"integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"fdir": "^6.5.0",
"picomatch": "^4.0.3"
},
"engines": {
"node": ">=12.0.0"
},
"funding": {
"url": "https://github.com/sponsors/SuperchupuDev"
}
},
"node_modules/tinyglobby/node_modules/fdir": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.0.0"
},
"peerDependencies": {
"picomatch": "^3 || ^4"
},
"peerDependenciesMeta": {
"picomatch": {
"optional": true
}
}
},
"node_modules/tinyglobby/node_modules/picomatch": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/ts-interface-checker": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true,
"license": "MIT"
}
}
}

View File

@ -1,128 +0,0 @@
declare namespace QuickLRU {
interface Options<KeyType, ValueType> {
/**
The maximum number of milliseconds an item should remain in the cache.
@default Infinity
By default, `maxAge` will be `Infinity`, which means that items will never expire.
Lazy expiration upon the next write or read call.
Individual expiration of an item can be specified by the `set(key, value, maxAge)` method.
*/
readonly maxAge?: number;
/**
The maximum number of items before evicting the least recently used items.
*/
readonly maxSize: number;
/**
Called right before an item is evicted from the cache.
Useful for side effects or for items like object URLs that need explicit cleanup (`revokeObjectURL`).
*/
onEviction?: (key: KeyType, value: ValueType) => void;
}
}
declare class QuickLRU<KeyType, ValueType>
implements Iterable<[KeyType, ValueType]> {
/**
The stored item count.
*/
readonly size: number;
/**
Simple ["Least Recently Used" (LRU) cache](https://en.m.wikipedia.org/wiki/Cache_replacement_policies#Least_Recently_Used_.28LRU.29).
The instance is [`iterable`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Iteration_protocols) so you can use it directly in a [`for…of`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/for...of) loop.
@example
```
import QuickLRU = require('quick-lru');
const lru = new QuickLRU({maxSize: 1000});
lru.set('🦄', '🌈');
lru.has('🦄');
//=> true
lru.get('🦄');
//=> '🌈'
```
*/
constructor(options: QuickLRU.Options<KeyType, ValueType>);
[Symbol.iterator](): IterableIterator<[KeyType, ValueType]>;
/**
Set an item. Returns the instance.
Individual expiration of an item can be specified with the `maxAge` option. If not specified, the global `maxAge` value will be used in case it is specified in the constructor, otherwise the item will never expire.
@returns The list instance.
*/
set(key: KeyType, value: ValueType, options?: {maxAge?: number}): this;
/**
Get an item.
@returns The stored item or `undefined`.
*/
get(key: KeyType): ValueType | undefined;
/**
Check if an item exists.
*/
has(key: KeyType): boolean;
/**
Get an item without marking it as recently used.
@returns The stored item or `undefined`.
*/
peek(key: KeyType): ValueType | undefined;
/**
Delete an item.
@returns `true` if the item is removed or `false` if the item doesn't exist.
*/
delete(key: KeyType): boolean;
/**
Delete all items.
*/
clear(): void;
/**
Update the `maxSize` in-place, discarding items as necessary. Insertion order is mostly preserved, though this is not a strong guarantee.
Useful for on-the-fly tuning of cache sizes in live systems.
*/
resize(maxSize: number): void;
/**
Iterable for all the keys.
*/
keys(): IterableIterator<KeyType>;
/**
Iterable for all the values.
*/
values(): IterableIterator<ValueType>;
/**
Iterable for all entries, starting with the oldest (ascending in recency).
*/
entriesAscending(): IterableIterator<[KeyType, ValueType]>;
/**
Iterable for all entries, starting with the newest (descending in recency).
*/
entriesDescending(): IterableIterator<[KeyType, ValueType]>;
}
export = QuickLRU;

View File

@ -1,263 +0,0 @@
'use strict';
class QuickLRU {
constructor(options = {}) {
if (!(options.maxSize && options.maxSize > 0)) {
throw new TypeError('`maxSize` must be a number greater than 0');
}
if (typeof options.maxAge === 'number' && options.maxAge === 0) {
throw new TypeError('`maxAge` must be a number greater than 0');
}
this.maxSize = options.maxSize;
this.maxAge = options.maxAge || Infinity;
this.onEviction = options.onEviction;
this.cache = new Map();
this.oldCache = new Map();
this._size = 0;
}
_emitEvictions(cache) {
if (typeof this.onEviction !== 'function') {
return;
}
for (const [key, item] of cache) {
this.onEviction(key, item.value);
}
}
_deleteIfExpired(key, item) {
if (typeof item.expiry === 'number' && item.expiry <= Date.now()) {
if (typeof this.onEviction === 'function') {
this.onEviction(key, item.value);
}
return this.delete(key);
}
return false;
}
_getOrDeleteIfExpired(key, item) {
const deleted = this._deleteIfExpired(key, item);
if (deleted === false) {
return item.value;
}
}
_getItemValue(key, item) {
return item.expiry ? this._getOrDeleteIfExpired(key, item) : item.value;
}
_peek(key, cache) {
const item = cache.get(key);
return this._getItemValue(key, item);
}
_set(key, value) {
this.cache.set(key, value);
this._size++;
if (this._size >= this.maxSize) {
this._size = 0;
this._emitEvictions(this.oldCache);
this.oldCache = this.cache;
this.cache = new Map();
}
}
_moveToRecent(key, item) {
this.oldCache.delete(key);
this._set(key, item);
}
* _entriesAscending() {
for (const item of this.oldCache) {
const [key, value] = item;
if (!this.cache.has(key)) {
const deleted = this._deleteIfExpired(key, value);
if (deleted === false) {
yield item;
}
}
}
for (const item of this.cache) {
const [key, value] = item;
const deleted = this._deleteIfExpired(key, value);
if (deleted === false) {
yield item;
}
}
}
get(key) {
if (this.cache.has(key)) {
const item = this.cache.get(key);
return this._getItemValue(key, item);
}
if (this.oldCache.has(key)) {
const item = this.oldCache.get(key);
if (this._deleteIfExpired(key, item) === false) {
this._moveToRecent(key, item);
return item.value;
}
}
}
set(key, value, {maxAge = this.maxAge === Infinity ? undefined : Date.now() + this.maxAge} = {}) {
if (this.cache.has(key)) {
this.cache.set(key, {
value,
maxAge
});
} else {
this._set(key, {value, expiry: maxAge});
}
}
has(key) {
if (this.cache.has(key)) {
return !this._deleteIfExpired(key, this.cache.get(key));
}
if (this.oldCache.has(key)) {
return !this._deleteIfExpired(key, this.oldCache.get(key));
}
return false;
}
peek(key) {
if (this.cache.has(key)) {
return this._peek(key, this.cache);
}
if (this.oldCache.has(key)) {
return this._peek(key, this.oldCache);
}
}
delete(key) {
const deleted = this.cache.delete(key);
if (deleted) {
this._size--;
}
return this.oldCache.delete(key) || deleted;
}
clear() {
this.cache.clear();
this.oldCache.clear();
this._size = 0;
}
resize(newSize) {
if (!(newSize && newSize > 0)) {
throw new TypeError('`maxSize` must be a number greater than 0');
}
const items = [...this._entriesAscending()];
const removeCount = items.length - newSize;
if (removeCount < 0) {
this.cache = new Map(items);
this.oldCache = new Map();
this._size = items.length;
} else {
if (removeCount > 0) {
this._emitEvictions(items.slice(0, removeCount));
}
this.oldCache = new Map(items.slice(removeCount));
this.cache = new Map();
this._size = 0;
}
this.maxSize = newSize;
}
* keys() {
for (const [key] of this) {
yield key;
}
}
* values() {
for (const [, value] of this) {
yield value;
}
}
* [Symbol.iterator]() {
for (const item of this.cache) {
const [key, value] = item;
const deleted = this._deleteIfExpired(key, value);
if (deleted === false) {
yield [key, value.value];
}
}
for (const item of this.oldCache) {
const [key, value] = item;
if (!this.cache.has(key)) {
const deleted = this._deleteIfExpired(key, value);
if (deleted === false) {
yield [key, value.value];
}
}
}
}
* entriesDescending() {
let items = [...this.cache];
for (let i = items.length - 1; i >= 0; --i) {
const item = items[i];
const [key, value] = item;
const deleted = this._deleteIfExpired(key, value);
if (deleted === false) {
yield [key, value.value];
}
}
items = [...this.oldCache];
for (let i = items.length - 1; i >= 0; --i) {
const item = items[i];
const [key, value] = item;
if (!this.cache.has(key)) {
const deleted = this._deleteIfExpired(key, value);
if (deleted === false) {
yield [key, value.value];
}
}
}
}
* entriesAscending() {
for (const [key, value] of this._entriesAscending()) {
yield [key, value.value];
}
}
get size() {
if (!this._size) {
return this.oldCache.size;
}
let oldCacheSize = 0;
for (const key of this.oldCache.keys()) {
if (!this.cache.has(key)) {
oldCacheSize++;
}
}
return Math.min(this._size + oldCacheSize, this.maxSize);
}
}
module.exports = QuickLRU;

View File

@ -1,9 +0,0 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,43 +0,0 @@
{
"name": "@alloc/quick-lru",
"version": "5.2.0",
"description": "Simple “Least Recently Used” (LRU) cache",
"license": "MIT",
"repository": "sindresorhus/quick-lru",
"funding": "https://github.com/sponsors/sindresorhus",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "https://sindresorhus.com"
},
"engines": {
"node": ">=10"
},
"scripts": {
"test": "xo && nyc ava && tsd"
},
"files": [
"index.js",
"index.d.ts"
],
"keywords": [
"lru",
"quick",
"cache",
"caching",
"least",
"recently",
"used",
"fast",
"map",
"hash",
"buffer"
],
"devDependencies": {
"ava": "^2.0.0",
"coveralls": "^3.0.3",
"nyc": "^15.0.0",
"tsd": "^0.11.0",
"xo": "^0.26.0"
}
}

View File

@ -1,139 +0,0 @@
# quick-lru [![Build Status](https://travis-ci.org/sindresorhus/quick-lru.svg?branch=master)](https://travis-ci.org/sindresorhus/quick-lru) [![Coverage Status](https://coveralls.io/repos/github/sindresorhus/quick-lru/badge.svg?branch=master)](https://coveralls.io/github/sindresorhus/quick-lru?branch=master)
> Simple [“Least Recently Used” (LRU) cache](https://en.m.wikipedia.org/wiki/Cache_replacement_policies#Least_Recently_Used_.28LRU.29)
Useful when you need to cache something and limit memory usage.
Inspired by the [`hashlru` algorithm](https://github.com/dominictarr/hashlru#algorithm), but instead uses [`Map`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map) to support keys of any type, not just strings, and values can be `undefined`.
## Install
```
$ npm install quick-lru
```
## Usage
```js
const QuickLRU = require('quick-lru');
const lru = new QuickLRU({maxSize: 1000});
lru.set('🦄', '🌈');
lru.has('🦄');
//=> true
lru.get('🦄');
//=> '🌈'
```
## API
### new QuickLRU(options?)
Returns a new instance.
### options
Type: `object`
#### maxSize
*Required*\
Type: `number`
The maximum number of items before evicting the least recently used items.
#### maxAge
Type: `number`\
Default: `Infinity`
The maximum number of milliseconds an item should remain in cache.
By default maxAge will be Infinity, which means that items will never expire.
Lazy expiration happens upon the next `write` or `read` call.
Individual expiration of an item can be specified by the `set(key, value, options)` method.
#### onEviction
*Optional*\
Type: `(key, value) => void`
Called right before an item is evicted from the cache.
Useful for side effects or for items like object URLs that need explicit cleanup (`revokeObjectURL`).
### Instance
The instance is [`iterable`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Iteration_protocols) so you can use it directly in a [`for…of`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/for...of) loop.
Both `key` and `value` can be of any type.
#### .set(key, value, options?)
Set an item. Returns the instance.
Individual expiration of an item can be specified with the `maxAge` option. If not specified, the global `maxAge` value will be used in case it is specified on the constructor, otherwise the item will never expire.
#### .get(key)
Get an item.
#### .has(key)
Check if an item exists.
#### .peek(key)
Get an item without marking it as recently used.
#### .delete(key)
Delete an item.
Returns `true` if the item is removed or `false` if the item doesn't exist.
#### .clear()
Delete all items.
#### .resize(maxSize)
Update the `maxSize`, discarding items as necessary. Insertion order is mostly preserved, though this is not a strong guarantee.
Useful for on-the-fly tuning of cache sizes in live systems.
#### .keys()
Iterable for all the keys.
#### .values()
Iterable for all the values.
#### .entriesAscending()
Iterable for all entries, starting with the oldest (ascending in recency).
#### .entriesDescending()
Iterable for all entries, starting with the newest (descending in recency).
#### .size
The stored item count.
---
<div align="center">
<b>
<a href="https://tidelift.com/subscription/pkg/npm-quick-lru?utm_source=npm-quick-lru&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a>
</b>
<br>
<sub>
Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies.
</sub>
</div>

View File

@ -1,19 +0,0 @@
Copyright 2024 Justin Ridgewell <justin@ridgewell.name>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,227 +0,0 @@
# @jridgewell/gen-mapping
> Generate source maps
`gen-mapping` allows you to generate a source map during transpilation or minification.
With a source map, you're able to trace the original location in the source file, either in Chrome's
DevTools or using a library like [`@jridgewell/trace-mapping`][trace-mapping].
You may already be familiar with the [`source-map`][source-map] package's `SourceMapGenerator`. This
provides the same `addMapping` and `setSourceContent` API.
## Installation
```sh
npm install @jridgewell/gen-mapping
```
## Usage
```typescript
import { GenMapping, addMapping, setSourceContent, toEncodedMap, toDecodedMap } from '@jridgewell/gen-mapping';
const map = new GenMapping({
file: 'output.js',
sourceRoot: 'https://example.com/',
});
setSourceContent(map, 'input.js', `function foo() {}`);
addMapping(map, {
// Lines start at line 1, columns at column 0.
generated: { line: 1, column: 0 },
source: 'input.js',
original: { line: 1, column: 0 },
});
addMapping(map, {
generated: { line: 1, column: 9 },
source: 'input.js',
original: { line: 1, column: 9 },
name: 'foo',
});
assert.deepEqual(toDecodedMap(map), {
version: 3,
file: 'output.js',
names: ['foo'],
sourceRoot: 'https://example.com/',
sources: ['input.js'],
sourcesContent: ['function foo() {}'],
mappings: [
[ [0, 0, 0, 0], [9, 0, 0, 9, 0] ]
],
});
assert.deepEqual(toEncodedMap(map), {
version: 3,
file: 'output.js',
names: ['foo'],
sourceRoot: 'https://example.com/',
sources: ['input.js'],
sourcesContent: ['function foo() {}'],
mappings: 'AAAA,SAASA',
});
```
### Smaller Sourcemaps
Not everything needs to be added to a sourcemap, and needless markings can cause signficantly
larger file sizes. `gen-mapping` exposes `maybeAddSegment`/`maybeAddMapping` APIs that will
intelligently determine if this marking adds useful information. If not, the marking will be
skipped.
```typescript
import { maybeAddMapping } from '@jridgewell/gen-mapping';
const map = new GenMapping();
// Adding a sourceless marking at the beginning of a line isn't useful.
maybeAddMapping(map, {
generated: { line: 1, column: 0 },
});
// Adding a new source marking is useful.
maybeAddMapping(map, {
generated: { line: 1, column: 0 },
source: 'input.js',
original: { line: 1, column: 0 },
});
// But adding another marking pointing to the exact same original location isn't, even if the
// generated column changed.
maybeAddMapping(map, {
generated: { line: 1, column: 9 },
source: 'input.js',
original: { line: 1, column: 0 },
});
assert.deepEqual(toEncodedMap(map), {
version: 3,
names: [],
sources: ['input.js'],
sourcesContent: [null],
mappings: 'AAAA',
});
```
## Benchmarks
```
node v18.0.0
amp.js.map
Memory Usage:
gen-mapping: addSegment 5852872 bytes
gen-mapping: addMapping 7716042 bytes
source-map-js 6143250 bytes
source-map-0.6.1 6124102 bytes
source-map-0.8.0 6121173 bytes
Smallest memory usage is gen-mapping: addSegment
Adding speed:
gen-mapping: addSegment x 441 ops/sec ±2.07% (90 runs sampled)
gen-mapping: addMapping x 350 ops/sec ±2.40% (86 runs sampled)
source-map-js: addMapping x 169 ops/sec ±2.42% (80 runs sampled)
source-map-0.6.1: addMapping x 167 ops/sec ±2.56% (80 runs sampled)
source-map-0.8.0: addMapping x 168 ops/sec ±2.52% (80 runs sampled)
Fastest is gen-mapping: addSegment
Generate speed:
gen-mapping: decoded output x 150,824,370 ops/sec ±0.07% (102 runs sampled)
gen-mapping: encoded output x 663 ops/sec ±0.22% (98 runs sampled)
source-map-js: encoded output x 197 ops/sec ±0.45% (84 runs sampled)
source-map-0.6.1: encoded output x 198 ops/sec ±0.33% (85 runs sampled)
source-map-0.8.0: encoded output x 197 ops/sec ±0.06% (93 runs sampled)
Fastest is gen-mapping: decoded output
***
babel.min.js.map
Memory Usage:
gen-mapping: addSegment 37578063 bytes
gen-mapping: addMapping 37212897 bytes
source-map-js 47638527 bytes
source-map-0.6.1 47690503 bytes
source-map-0.8.0 47470188 bytes
Smallest memory usage is gen-mapping: addMapping
Adding speed:
gen-mapping: addSegment x 31.05 ops/sec ±8.31% (43 runs sampled)
gen-mapping: addMapping x 29.83 ops/sec ±7.36% (51 runs sampled)
source-map-js: addMapping x 20.73 ops/sec ±6.22% (38 runs sampled)
source-map-0.6.1: addMapping x 20.03 ops/sec ±10.51% (38 runs sampled)
source-map-0.8.0: addMapping x 19.30 ops/sec ±8.27% (37 runs sampled)
Fastest is gen-mapping: addSegment
Generate speed:
gen-mapping: decoded output x 381,379,234 ops/sec ±0.29% (96 runs sampled)
gen-mapping: encoded output x 95.15 ops/sec ±2.98% (72 runs sampled)
source-map-js: encoded output x 15.20 ops/sec ±7.41% (33 runs sampled)
source-map-0.6.1: encoded output x 16.36 ops/sec ±10.46% (31 runs sampled)
source-map-0.8.0: encoded output x 16.06 ops/sec ±6.45% (31 runs sampled)
Fastest is gen-mapping: decoded output
***
preact.js.map
Memory Usage:
gen-mapping: addSegment 416247 bytes
gen-mapping: addMapping 419824 bytes
source-map-js 1024619 bytes
source-map-0.6.1 1146004 bytes
source-map-0.8.0 1113250 bytes
Smallest memory usage is gen-mapping: addSegment
Adding speed:
gen-mapping: addSegment x 13,755 ops/sec ±0.15% (98 runs sampled)
gen-mapping: addMapping x 13,013 ops/sec ±0.11% (101 runs sampled)
source-map-js: addMapping x 4,564 ops/sec ±0.21% (98 runs sampled)
source-map-0.6.1: addMapping x 4,562 ops/sec ±0.11% (99 runs sampled)
source-map-0.8.0: addMapping x 4,593 ops/sec ±0.11% (100 runs sampled)
Fastest is gen-mapping: addSegment
Generate speed:
gen-mapping: decoded output x 379,864,020 ops/sec ±0.23% (93 runs sampled)
gen-mapping: encoded output x 14,368 ops/sec ±4.07% (82 runs sampled)
source-map-js: encoded output x 5,261 ops/sec ±0.21% (99 runs sampled)
source-map-0.6.1: encoded output x 5,124 ops/sec ±0.58% (99 runs sampled)
source-map-0.8.0: encoded output x 5,434 ops/sec ±0.33% (96 runs sampled)
Fastest is gen-mapping: decoded output
***
react.js.map
Memory Usage:
gen-mapping: addSegment 975096 bytes
gen-mapping: addMapping 1102981 bytes
source-map-js 2918836 bytes
source-map-0.6.1 2885435 bytes
source-map-0.8.0 2874336 bytes
Smallest memory usage is gen-mapping: addSegment
Adding speed:
gen-mapping: addSegment x 4,772 ops/sec ±0.15% (100 runs sampled)
gen-mapping: addMapping x 4,456 ops/sec ±0.13% (97 runs sampled)
source-map-js: addMapping x 1,618 ops/sec ±0.24% (97 runs sampled)
source-map-0.6.1: addMapping x 1,622 ops/sec ±0.12% (99 runs sampled)
source-map-0.8.0: addMapping x 1,631 ops/sec ±0.12% (100 runs sampled)
Fastest is gen-mapping: addSegment
Generate speed:
gen-mapping: decoded output x 379,107,695 ops/sec ±0.07% (99 runs sampled)
gen-mapping: encoded output x 5,421 ops/sec ±1.60% (89 runs sampled)
source-map-js: encoded output x 2,113 ops/sec ±1.81% (98 runs sampled)
source-map-0.6.1: encoded output x 2,126 ops/sec ±0.10% (100 runs sampled)
source-map-0.8.0: encoded output x 2,176 ops/sec ±0.39% (98 runs sampled)
Fastest is gen-mapping: decoded output
```
[source-map]: https://www.npmjs.com/package/source-map
[trace-mapping]: https://github.com/jridgewell/sourcemaps/tree/main/packages/trace-mapping

View File

@ -1,67 +0,0 @@
{
"name": "@jridgewell/gen-mapping",
"version": "0.3.13",
"description": "Generate source maps",
"keywords": [
"source",
"map"
],
"main": "dist/gen-mapping.umd.js",
"module": "dist/gen-mapping.mjs",
"types": "types/gen-mapping.d.cts",
"files": [
"dist",
"src",
"types"
],
"exports": {
".": [
{
"import": {
"types": "./types/gen-mapping.d.mts",
"default": "./dist/gen-mapping.mjs"
},
"default": {
"types": "./types/gen-mapping.d.cts",
"default": "./dist/gen-mapping.umd.js"
}
},
"./dist/gen-mapping.umd.js"
],
"./package.json": "./package.json"
},
"scripts": {
"benchmark": "run-s build:code benchmark:*",
"benchmark:install": "cd benchmark && npm install",
"benchmark:only": "node --expose-gc benchmark/index.js",
"build": "run-s -n build:code build:types",
"build:code": "node ../../esbuild.mjs gen-mapping.ts",
"build:types": "run-s build:types:force build:types:emit build:types:mts",
"build:types:force": "rimraf tsconfig.build.tsbuildinfo",
"build:types:emit": "tsc --project tsconfig.build.json",
"build:types:mts": "node ../../mts-types.mjs",
"clean": "run-s -n clean:code clean:types",
"clean:code": "tsc --build --clean tsconfig.build.json",
"clean:types": "rimraf dist types",
"test": "run-s -n test:types test:only test:format",
"test:format": "prettier --check '{src,test}/**/*.ts'",
"test:only": "mocha",
"test:types": "eslint '{src,test}/**/*.ts'",
"lint": "run-s -n lint:types lint:format",
"lint:format": "npm run test:format -- --write",
"lint:types": "npm run test:types -- --fix",
"prepublishOnly": "npm run-s -n build test"
},
"homepage": "https://github.com/jridgewell/sourcemaps/tree/main/packages/gen-mapping",
"repository": {
"type": "git",
"url": "git+https://github.com/jridgewell/sourcemaps.git",
"directory": "packages/gen-mapping"
},
"author": "Justin Ridgewell <justin@ridgewell.name>",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0",
"@jridgewell/trace-mapping": "^0.3.24"
}
}

View File

@ -1,614 +0,0 @@
import { SetArray, put, remove } from './set-array';
import {
encode,
// encodeGeneratedRanges,
// encodeOriginalScopes
} from '@jridgewell/sourcemap-codec';
import { TraceMap, decodedMappings } from '@jridgewell/trace-mapping';
import {
COLUMN,
SOURCES_INDEX,
SOURCE_LINE,
SOURCE_COLUMN,
NAMES_INDEX,
} from './sourcemap-segment';
import type { SourceMapInput } from '@jridgewell/trace-mapping';
// import type { OriginalScope, GeneratedRange } from '@jridgewell/sourcemap-codec';
import type { SourceMapSegment } from './sourcemap-segment';
import type {
DecodedSourceMap,
EncodedSourceMap,
Pos,
Mapping,
// BindingExpressionRange,
// OriginalPos,
// OriginalScopeInfo,
// GeneratedRangeInfo,
} from './types';
export type { DecodedSourceMap, EncodedSourceMap, Mapping };
export type Options = {
file?: string | null;
sourceRoot?: string | null;
};
const NO_NAME = -1;
/**
* Provides the state to generate a sourcemap.
*/
export class GenMapping {
declare private _names: SetArray<string>;
declare private _sources: SetArray<string>;
declare private _sourcesContent: (string | null)[];
declare private _mappings: SourceMapSegment[][];
// private declare _originalScopes: OriginalScope[][];
// private declare _generatedRanges: GeneratedRange[];
declare private _ignoreList: SetArray<number>;
declare file: string | null | undefined;
declare sourceRoot: string | null | undefined;
constructor({ file, sourceRoot }: Options = {}) {
this._names = new SetArray();
this._sources = new SetArray();
this._sourcesContent = [];
this._mappings = [];
// this._originalScopes = [];
// this._generatedRanges = [];
this.file = file;
this.sourceRoot = sourceRoot;
this._ignoreList = new SetArray();
}
}
interface PublicMap {
_names: GenMapping['_names'];
_sources: GenMapping['_sources'];
_sourcesContent: GenMapping['_sourcesContent'];
_mappings: GenMapping['_mappings'];
// _originalScopes: GenMapping['_originalScopes'];
// _generatedRanges: GenMapping['_generatedRanges'];
_ignoreList: GenMapping['_ignoreList'];
}
/**
* Typescript doesn't allow friend access to private fields, so this just casts the map into a type
* with public access modifiers.
*/
function cast(map: unknown): PublicMap {
return map as any;
}
/**
* A low-level API to associate a generated position with an original source position. Line and
* column here are 0-based, unlike `addMapping`.
*/
export function addSegment(
map: GenMapping,
genLine: number,
genColumn: number,
source?: null,
sourceLine?: null,
sourceColumn?: null,
name?: null,
content?: null,
): void;
export function addSegment(
map: GenMapping,
genLine: number,
genColumn: number,
source: string,
sourceLine: number,
sourceColumn: number,
name?: null,
content?: string | null,
): void;
export function addSegment(
map: GenMapping,
genLine: number,
genColumn: number,
source: string,
sourceLine: number,
sourceColumn: number,
name: string,
content?: string | null,
): void;
export function addSegment(
map: GenMapping,
genLine: number,
genColumn: number,
source?: string | null,
sourceLine?: number | null,
sourceColumn?: number | null,
name?: string | null,
content?: string | null,
): void {
return addSegmentInternal(
false,
map,
genLine,
genColumn,
source,
sourceLine,
sourceColumn,
name,
content,
);
}
/**
* A high-level API to associate a generated position with an original source position. Line is
* 1-based, but column is 0-based, due to legacy behavior in `source-map` library.
*/
export function addMapping(
map: GenMapping,
mapping: {
generated: Pos;
source?: null;
original?: null;
name?: null;
content?: null;
},
): void;
export function addMapping(
map: GenMapping,
mapping: {
generated: Pos;
source: string;
original: Pos;
name?: null;
content?: string | null;
},
): void;
export function addMapping(
map: GenMapping,
mapping: {
generated: Pos;
source: string;
original: Pos;
name: string;
content?: string | null;
},
): void;
export function addMapping(
map: GenMapping,
mapping: {
generated: Pos;
source?: string | null;
original?: Pos | null;
name?: string | null;
content?: string | null;
},
): void {
return addMappingInternal(false, map, mapping as Parameters<typeof addMappingInternal>[2]);
}
/**
* Same as `addSegment`, but will only add the segment if it generates useful information in the
* resulting map. This only works correctly if segments are added **in order**, meaning you should
* not add a segment with a lower generated line/column than one that came before.
*/
export const maybeAddSegment: typeof addSegment = (
map,
genLine,
genColumn,
source,
sourceLine,
sourceColumn,
name,
content,
) => {
return addSegmentInternal(
true,
map,
genLine,
genColumn,
source,
sourceLine,
sourceColumn,
name,
content,
);
};
/**
* Same as `addMapping`, but will only add the mapping if it generates useful information in the
* resulting map. This only works correctly if mappings are added **in order**, meaning you should
* not add a mapping with a lower generated line/column than one that came before.
*/
export const maybeAddMapping: typeof addMapping = (map, mapping) => {
return addMappingInternal(true, map, mapping as Parameters<typeof addMappingInternal>[2]);
};
/**
* Adds/removes the content of the source file to the source map.
*/
export function setSourceContent(map: GenMapping, source: string, content: string | null): void {
const {
_sources: sources,
_sourcesContent: sourcesContent,
// _originalScopes: originalScopes,
} = cast(map);
const index = put(sources, source);
sourcesContent[index] = content;
// if (index === originalScopes.length) originalScopes[index] = [];
}
export function setIgnore(map: GenMapping, source: string, ignore = true) {
const {
_sources: sources,
_sourcesContent: sourcesContent,
_ignoreList: ignoreList,
// _originalScopes: originalScopes,
} = cast(map);
const index = put(sources, source);
if (index === sourcesContent.length) sourcesContent[index] = null;
// if (index === originalScopes.length) originalScopes[index] = [];
if (ignore) put(ignoreList, index);
else remove(ignoreList, index);
}
/**
* Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects
* a sourcemap, or to JSON.stringify.
*/
export function toDecodedMap(map: GenMapping): DecodedSourceMap {
const {
_mappings: mappings,
_sources: sources,
_sourcesContent: sourcesContent,
_names: names,
_ignoreList: ignoreList,
// _originalScopes: originalScopes,
// _generatedRanges: generatedRanges,
} = cast(map);
removeEmptyFinalLines(mappings);
return {
version: 3,
file: map.file || undefined,
names: names.array,
sourceRoot: map.sourceRoot || undefined,
sources: sources.array,
sourcesContent,
mappings,
// originalScopes,
// generatedRanges,
ignoreList: ignoreList.array,
};
}
/**
* Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects
* a sourcemap, or to JSON.stringify.
*/
export function toEncodedMap(map: GenMapping): EncodedSourceMap {
const decoded = toDecodedMap(map);
return Object.assign({}, decoded, {
// originalScopes: decoded.originalScopes.map((os) => encodeOriginalScopes(os)),
// generatedRanges: encodeGeneratedRanges(decoded.generatedRanges as GeneratedRange[]),
mappings: encode(decoded.mappings as SourceMapSegment[][]),
});
}
/**
* Constructs a new GenMapping, using the already present mappings of the input.
*/
export function fromMap(input: SourceMapInput): GenMapping {
const map = new TraceMap(input);
const gen = new GenMapping({ file: map.file, sourceRoot: map.sourceRoot });
putAll(cast(gen)._names, map.names);
putAll(cast(gen)._sources, map.sources as string[]);
cast(gen)._sourcesContent = map.sourcesContent || map.sources.map(() => null);
cast(gen)._mappings = decodedMappings(map) as GenMapping['_mappings'];
// TODO: implement originalScopes/generatedRanges
if (map.ignoreList) putAll(cast(gen)._ignoreList, map.ignoreList);
return gen;
}
/**
* Returns an array of high-level mapping objects for every recorded segment, which could then be
* passed to the `source-map` library.
*/
export function allMappings(map: GenMapping): Mapping[] {
const out: Mapping[] = [];
const { _mappings: mappings, _sources: sources, _names: names } = cast(map);
for (let i = 0; i < mappings.length; i++) {
const line = mappings[i];
for (let j = 0; j < line.length; j++) {
const seg = line[j];
const generated = { line: i + 1, column: seg[COLUMN] };
let source: string | undefined = undefined;
let original: Pos | undefined = undefined;
let name: string | undefined = undefined;
if (seg.length !== 1) {
source = sources.array[seg[SOURCES_INDEX]];
original = { line: seg[SOURCE_LINE] + 1, column: seg[SOURCE_COLUMN] };
if (seg.length === 5) name = names.array[seg[NAMES_INDEX]];
}
out.push({ generated, source, original, name } as Mapping);
}
}
return out;
}
// This split declaration is only so that terser can elminiate the static initialization block.
function addSegmentInternal<S extends string | null | undefined>(
skipable: boolean,
map: GenMapping,
genLine: number,
genColumn: number,
source: S,
sourceLine: S extends string ? number : null | undefined,
sourceColumn: S extends string ? number : null | undefined,
name: S extends string ? string | null | undefined : null | undefined,
content: S extends string ? string | null | undefined : null | undefined,
): void {
const {
_mappings: mappings,
_sources: sources,
_sourcesContent: sourcesContent,
_names: names,
// _originalScopes: originalScopes,
} = cast(map);
const line = getIndex(mappings, genLine);
const index = getColumnIndex(line, genColumn);
if (!source) {
if (skipable && skipSourceless(line, index)) return;
return insert(line, index, [genColumn]);
}
// Sigh, TypeScript can't figure out sourceLine and sourceColumn aren't nullish if source
// isn't nullish.
assert<number>(sourceLine);
assert<number>(sourceColumn);
const sourcesIndex = put(sources, source);
const namesIndex = name ? put(names, name) : NO_NAME;
if (sourcesIndex === sourcesContent.length) sourcesContent[sourcesIndex] = content ?? null;
// if (sourcesIndex === originalScopes.length) originalScopes[sourcesIndex] = [];
if (skipable && skipSource(line, index, sourcesIndex, sourceLine, sourceColumn, namesIndex)) {
return;
}
return insert(
line,
index,
name
? [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex]
: [genColumn, sourcesIndex, sourceLine, sourceColumn],
);
}
function assert<T>(_val: unknown): asserts _val is T {
// noop.
}
function getIndex<T>(arr: T[][], index: number): T[] {
for (let i = arr.length; i <= index; i++) {
arr[i] = [];
}
return arr[index];
}
function getColumnIndex(line: SourceMapSegment[], genColumn: number): number {
let index = line.length;
for (let i = index - 1; i >= 0; index = i--) {
const current = line[i];
if (genColumn >= current[COLUMN]) break;
}
return index;
}
function insert<T>(array: T[], index: number, value: T) {
for (let i = array.length; i > index; i--) {
array[i] = array[i - 1];
}
array[index] = value;
}
function removeEmptyFinalLines(mappings: SourceMapSegment[][]) {
const { length } = mappings;
let len = length;
for (let i = len - 1; i >= 0; len = i, i--) {
if (mappings[i].length > 0) break;
}
if (len < length) mappings.length = len;
}
function putAll<T extends string | number>(setarr: SetArray<T>, array: T[]) {
for (let i = 0; i < array.length; i++) put(setarr, array[i]);
}
function skipSourceless(line: SourceMapSegment[], index: number): boolean {
// The start of a line is already sourceless, so adding a sourceless segment to the beginning
// doesn't generate any useful information.
if (index === 0) return true;
const prev = line[index - 1];
// If the previous segment is also sourceless, then adding another sourceless segment doesn't
// genrate any new information. Else, this segment will end the source/named segment and point to
// a sourceless position, which is useful.
return prev.length === 1;
}
function skipSource(
line: SourceMapSegment[],
index: number,
sourcesIndex: number,
sourceLine: number,
sourceColumn: number,
namesIndex: number,
): boolean {
// A source/named segment at the start of a line gives position at that genColumn
if (index === 0) return false;
const prev = line[index - 1];
// If the previous segment is sourceless, then we're transitioning to a source.
if (prev.length === 1) return false;
// If the previous segment maps to the exact same source position, then this segment doesn't
// provide any new position information.
return (
sourcesIndex === prev[SOURCES_INDEX] &&
sourceLine === prev[SOURCE_LINE] &&
sourceColumn === prev[SOURCE_COLUMN] &&
namesIndex === (prev.length === 5 ? prev[NAMES_INDEX] : NO_NAME)
);
}
function addMappingInternal<S extends string | null | undefined>(
skipable: boolean,
map: GenMapping,
mapping: {
generated: Pos;
source: S;
original: S extends string ? Pos : null | undefined;
name: S extends string ? string | null | undefined : null | undefined;
content: S extends string ? string | null | undefined : null | undefined;
},
) {
const { generated, source, original, name, content } = mapping;
if (!source) {
return addSegmentInternal(
skipable,
map,
generated.line - 1,
generated.column,
null,
null,
null,
null,
null,
);
}
assert<Pos>(original);
return addSegmentInternal(
skipable,
map,
generated.line - 1,
generated.column,
source as string,
original.line - 1,
original.column,
name,
content,
);
}
/*
export function addOriginalScope(
map: GenMapping,
data: {
start: Pos;
end: Pos;
source: string;
kind: string;
name?: string;
variables?: string[];
},
): OriginalScopeInfo {
const { start, end, source, kind, name, variables } = data;
const {
_sources: sources,
_sourcesContent: sourcesContent,
_originalScopes: originalScopes,
_names: names,
} = cast(map);
const index = put(sources, source);
if (index === sourcesContent.length) sourcesContent[index] = null;
if (index === originalScopes.length) originalScopes[index] = [];
const kindIndex = put(names, kind);
const scope: OriginalScope = name
? [start.line - 1, start.column, end.line - 1, end.column, kindIndex, put(names, name)]
: [start.line - 1, start.column, end.line - 1, end.column, kindIndex];
if (variables) {
scope.vars = variables.map((v) => put(names, v));
}
const len = originalScopes[index].push(scope);
return [index, len - 1, variables];
}
*/
// Generated Ranges
/*
export function addGeneratedRange(
map: GenMapping,
data: {
start: Pos;
isScope: boolean;
originalScope?: OriginalScopeInfo;
callsite?: OriginalPos;
},
): GeneratedRangeInfo {
const { start, isScope, originalScope, callsite } = data;
const {
_originalScopes: originalScopes,
_sources: sources,
_sourcesContent: sourcesContent,
_generatedRanges: generatedRanges,
} = cast(map);
const range: GeneratedRange = [
start.line - 1,
start.column,
0,
0,
originalScope ? originalScope[0] : -1,
originalScope ? originalScope[1] : -1,
];
if (originalScope?.[2]) {
range.bindings = originalScope[2].map(() => [[-1]]);
}
if (callsite) {
const index = put(sources, callsite.source);
if (index === sourcesContent.length) sourcesContent[index] = null;
if (index === originalScopes.length) originalScopes[index] = [];
range.callsite = [index, callsite.line - 1, callsite.column];
}
if (isScope) range.isScope = true;
generatedRanges.push(range);
return [range, originalScope?.[2]];
}
export function setEndPosition(range: GeneratedRangeInfo, pos: Pos) {
range[0][2] = pos.line - 1;
range[0][3] = pos.column;
}
export function addBinding(
map: GenMapping,
range: GeneratedRangeInfo,
variable: string,
expression: string | BindingExpressionRange,
) {
const { _names: names } = cast(map);
const bindings = (range[0].bindings ||= []);
const vars = range[1];
const index = vars!.indexOf(variable);
const binding = getIndex(bindings, index);
if (typeof expression === 'string') binding[0] = [put(names, expression)];
else {
const { start } = expression;
binding.push([put(names, expression.expression), start.line - 1, start.column]);
}
}
*/

View File

@ -1,82 +0,0 @@
type Key = string | number | symbol;
/**
* SetArray acts like a `Set` (allowing only one occurrence of a string `key`), but provides the
* index of the `key` in the backing array.
*
* This is designed to allow synchronizing a second array with the contents of the backing array,
* like how in a sourcemap `sourcesContent[i]` is the source content associated with `source[i]`,
* and there are never duplicates.
*/
export class SetArray<T extends Key = Key> {
declare private _indexes: Record<T, number | undefined>;
declare array: readonly T[];
constructor() {
this._indexes = { __proto__: null } as any;
this.array = [];
}
}
interface PublicSet<T extends Key> {
array: T[];
_indexes: SetArray<T>['_indexes'];
}
/**
* Typescript doesn't allow friend access to private fields, so this just casts the set into a type
* with public access modifiers.
*/
function cast<T extends Key>(set: SetArray<T>): PublicSet<T> {
return set as any;
}
/**
* Gets the index associated with `key` in the backing array, if it is already present.
*/
export function get<T extends Key>(setarr: SetArray<T>, key: T): number | undefined {
return cast(setarr)._indexes[key];
}
/**
* Puts `key` into the backing array, if it is not already present. Returns
* the index of the `key` in the backing array.
*/
export function put<T extends Key>(setarr: SetArray<T>, key: T): number {
// The key may or may not be present. If it is present, it's a number.
const index = get(setarr, key);
if (index !== undefined) return index;
const { array, _indexes: indexes } = cast(setarr);
const length = array.push(key);
return (indexes[key] = length - 1);
}
/**
* Pops the last added item out of the SetArray.
*/
export function pop<T extends Key>(setarr: SetArray<T>): void {
const { array, _indexes: indexes } = cast(setarr);
if (array.length === 0) return;
const last = array.pop()!;
indexes[last] = undefined;
}
/**
* Removes the key, if it exists in the set.
*/
export function remove<T extends Key>(setarr: SetArray<T>, key: T): void {
const index = get(setarr, key);
if (index === undefined) return;
const { array, _indexes: indexes } = cast(setarr);
for (let i = index + 1; i < array.length; i++) {
const k = array[i];
array[i - 1] = k;
indexes[k]!--;
}
indexes[key] = undefined;
array.pop();
}

View File

@ -1,16 +0,0 @@
type GeneratedColumn = number;
type SourcesIndex = number;
type SourceLine = number;
type SourceColumn = number;
type NamesIndex = number;
export type SourceMapSegment =
| [GeneratedColumn]
| [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn]
| [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex];
export const COLUMN = 0;
export const SOURCES_INDEX = 1;
export const SOURCE_LINE = 2;
export const SOURCE_COLUMN = 3;
export const NAMES_INDEX = 4;

View File

@ -1,61 +0,0 @@
// import type { GeneratedRange, OriginalScope } from '@jridgewell/sourcemap-codec';
import type { SourceMapSegment } from './sourcemap-segment';
export interface SourceMapV3 {
file?: string | null;
names: readonly string[];
sourceRoot?: string;
sources: readonly (string | null)[];
sourcesContent?: readonly (string | null)[];
version: 3;
ignoreList?: readonly number[];
}
export interface EncodedSourceMap extends SourceMapV3 {
mappings: string;
// originalScopes: string[];
// generatedRanges: string;
}
export interface DecodedSourceMap extends SourceMapV3 {
mappings: readonly SourceMapSegment[][];
// originalScopes: readonly OriginalScope[][];
// generatedRanges: readonly GeneratedRange[];
}
export interface Pos {
line: number; // 1-based
column: number; // 0-based
}
export interface OriginalPos extends Pos {
source: string;
}
export interface BindingExpressionRange {
start: Pos;
expression: string;
}
// export type OriginalScopeInfo = [number, number, string[] | undefined];
// export type GeneratedRangeInfo = [GeneratedRange, string[] | undefined];
export type Mapping =
| {
generated: Pos;
source: undefined;
original: undefined;
name: undefined;
}
| {
generated: Pos;
source: string;
original: Pos;
name: string;
}
| {
generated: Pos;
source: string;
original: Pos;
name: undefined;
};

View File

@ -1,89 +0,0 @@
import type { SourceMapInput } from '@jridgewell/trace-mapping';
import type { DecodedSourceMap, EncodedSourceMap, Pos, Mapping } from './types.cts';
export type { DecodedSourceMap, EncodedSourceMap, Mapping };
export type Options = {
file?: string | null;
sourceRoot?: string | null;
};
/**
* Provides the state to generate a sourcemap.
*/
export declare class GenMapping {
private _names;
private _sources;
private _sourcesContent;
private _mappings;
private _ignoreList;
file: string | null | undefined;
sourceRoot: string | null | undefined;
constructor({ file, sourceRoot }?: Options);
}
/**
* A low-level API to associate a generated position with an original source position. Line and
* column here are 0-based, unlike `addMapping`.
*/
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source?: null, sourceLine?: null, sourceColumn?: null, name?: null, content?: null): void;
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name?: null, content?: string | null): void;
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name: string, content?: string | null): void;
/**
* A high-level API to associate a generated position with an original source position. Line is
* 1-based, but column is 0-based, due to legacy behavior in `source-map` library.
*/
export declare function addMapping(map: GenMapping, mapping: {
generated: Pos;
source?: null;
original?: null;
name?: null;
content?: null;
}): void;
export declare function addMapping(map: GenMapping, mapping: {
generated: Pos;
source: string;
original: Pos;
name?: null;
content?: string | null;
}): void;
export declare function addMapping(map: GenMapping, mapping: {
generated: Pos;
source: string;
original: Pos;
name: string;
content?: string | null;
}): void;
/**
* Same as `addSegment`, but will only add the segment if it generates useful information in the
* resulting map. This only works correctly if segments are added **in order**, meaning you should
* not add a segment with a lower generated line/column than one that came before.
*/
export declare const maybeAddSegment: typeof addSegment;
/**
* Same as `addMapping`, but will only add the mapping if it generates useful information in the
* resulting map. This only works correctly if mappings are added **in order**, meaning you should
* not add a mapping with a lower generated line/column than one that came before.
*/
export declare const maybeAddMapping: typeof addMapping;
/**
* Adds/removes the content of the source file to the source map.
*/
export declare function setSourceContent(map: GenMapping, source: string, content: string | null): void;
export declare function setIgnore(map: GenMapping, source: string, ignore?: boolean): void;
/**
* Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects
* a sourcemap, or to JSON.stringify.
*/
export declare function toDecodedMap(map: GenMapping): DecodedSourceMap;
/**
* Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects
* a sourcemap, or to JSON.stringify.
*/
export declare function toEncodedMap(map: GenMapping): EncodedSourceMap;
/**
* Constructs a new GenMapping, using the already present mappings of the input.
*/
export declare function fromMap(input: SourceMapInput): GenMapping;
/**
* Returns an array of high-level mapping objects for every recorded segment, which could then be
* passed to the `source-map` library.
*/
export declare function allMappings(map: GenMapping): Mapping[];
//# sourceMappingURL=gen-mapping.d.ts.map

View File

@ -1 +0,0 @@
{"version":3,"file":"gen-mapping.d.ts","sourceRoot":"","sources":["../src/gen-mapping.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,GAAG,EACH,OAAO,EAKR,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC;AAE5D,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAIF;;GAEG;AACH,qBAAa,UAAU;IACrB,QAAgB,MAAM,CAAmB;IACzC,QAAgB,QAAQ,CAAmB;IAC3C,QAAgB,eAAe,CAAoB;IACnD,QAAgB,SAAS,CAAuB;IAGhD,QAAgB,WAAW,CAAmB;IACtC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;gBAElC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAE,OAAY;CAW/C;AAoBD;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,IAAI,EACb,UAAU,CAAC,EAAE,IAAI,EACjB,YAAY,CAAC,EAAE,IAAI,EACnB,IAAI,CAAC,EAAE,IAAI,EACX,OAAO,CAAC,EAAE,IAAI,GACb,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,IAAI,EACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,IAAI,CAAC;AAwBR;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,IAAI,CAAC;CAChB,GACA,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GACA,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GACA,IAAI,CAAC;AAcR;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,UAqBpC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,UAEpC,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAS9F;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAO,QAYvE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,CAwB9D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,CAO9D;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU,CAYzD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,EAAE,CA0BtD"}

View File

@ -1,89 +0,0 @@
import type { SourceMapInput } from '@jridgewell/trace-mapping';
import type { DecodedSourceMap, EncodedSourceMap, Pos, Mapping } from './types.mts';
export type { DecodedSourceMap, EncodedSourceMap, Mapping };
export type Options = {
file?: string | null;
sourceRoot?: string | null;
};
/**
* Provides the state to generate a sourcemap.
*/
export declare class GenMapping {
private _names;
private _sources;
private _sourcesContent;
private _mappings;
private _ignoreList;
file: string | null | undefined;
sourceRoot: string | null | undefined;
constructor({ file, sourceRoot }?: Options);
}
/**
* A low-level API to associate a generated position with an original source position. Line and
* column here are 0-based, unlike `addMapping`.
*/
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source?: null, sourceLine?: null, sourceColumn?: null, name?: null, content?: null): void;
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name?: null, content?: string | null): void;
export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name: string, content?: string | null): void;
/**
* A high-level API to associate a generated position with an original source position. Line is
* 1-based, but column is 0-based, due to legacy behavior in `source-map` library.
*/
export declare function addMapping(map: GenMapping, mapping: {
generated: Pos;
source?: null;
original?: null;
name?: null;
content?: null;
}): void;
export declare function addMapping(map: GenMapping, mapping: {
generated: Pos;
source: string;
original: Pos;
name?: null;
content?: string | null;
}): void;
export declare function addMapping(map: GenMapping, mapping: {
generated: Pos;
source: string;
original: Pos;
name: string;
content?: string | null;
}): void;
/**
* Same as `addSegment`, but will only add the segment if it generates useful information in the
* resulting map. This only works correctly if segments are added **in order**, meaning you should
* not add a segment with a lower generated line/column than one that came before.
*/
export declare const maybeAddSegment: typeof addSegment;
/**
* Same as `addMapping`, but will only add the mapping if it generates useful information in the
* resulting map. This only works correctly if mappings are added **in order**, meaning you should
* not add a mapping with a lower generated line/column than one that came before.
*/
export declare const maybeAddMapping: typeof addMapping;
/**
* Adds/removes the content of the source file to the source map.
*/
export declare function setSourceContent(map: GenMapping, source: string, content: string | null): void;
export declare function setIgnore(map: GenMapping, source: string, ignore?: boolean): void;
/**
* Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects
* a sourcemap, or to JSON.stringify.
*/
export declare function toDecodedMap(map: GenMapping): DecodedSourceMap;
/**
* Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects
* a sourcemap, or to JSON.stringify.
*/
export declare function toEncodedMap(map: GenMapping): EncodedSourceMap;
/**
* Constructs a new GenMapping, using the already present mappings of the input.
*/
export declare function fromMap(input: SourceMapInput): GenMapping;
/**
* Returns an array of high-level mapping objects for every recorded segment, which could then be
* passed to the `source-map` library.
*/
export declare function allMappings(map: GenMapping): Mapping[];
//# sourceMappingURL=gen-mapping.d.ts.map

View File

@ -1 +0,0 @@
{"version":3,"file":"gen-mapping.d.ts","sourceRoot":"","sources":["../src/gen-mapping.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,GAAG,EACH,OAAO,EAKR,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC;AAE5D,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAIF;;GAEG;AACH,qBAAa,UAAU;IACrB,QAAgB,MAAM,CAAmB;IACzC,QAAgB,QAAQ,CAAmB;IAC3C,QAAgB,eAAe,CAAoB;IACnD,QAAgB,SAAS,CAAuB;IAGhD,QAAgB,WAAW,CAAmB;IACtC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;gBAElC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAE,OAAY;CAW/C;AAoBD;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,IAAI,EACb,UAAU,CAAC,EAAE,IAAI,EACjB,YAAY,CAAC,EAAE,IAAI,EACnB,IAAI,CAAC,EAAE,IAAI,EACX,OAAO,CAAC,EAAE,IAAI,GACb,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,IAAI,EACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,IAAI,CAAC;AAwBR;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,IAAI,CAAC;CAChB,GACA,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GACA,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GACA,IAAI,CAAC;AAcR;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,UAqBpC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,UAEpC,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAS9F;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAO,QAYvE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,CAwB9D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,CAO9D;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU,CAYzD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,EAAE,CA0BtD"}

View File

@ -1,33 +0,0 @@
type Key = string | number | symbol;
/**
* SetArray acts like a `Set` (allowing only one occurrence of a string `key`), but provides the
* index of the `key` in the backing array.
*
* This is designed to allow synchronizing a second array with the contents of the backing array,
* like how in a sourcemap `sourcesContent[i]` is the source content associated with `source[i]`,
* and there are never duplicates.
*/
export declare class SetArray<T extends Key = Key> {
private _indexes;
array: readonly T[];
constructor();
}
/**
* Gets the index associated with `key` in the backing array, if it is already present.
*/
export declare function get<T extends Key>(setarr: SetArray<T>, key: T): number | undefined;
/**
* Puts `key` into the backing array, if it is not already present. Returns
* the index of the `key` in the backing array.
*/
export declare function put<T extends Key>(setarr: SetArray<T>, key: T): number;
/**
* Pops the last added item out of the SetArray.
*/
export declare function pop<T extends Key>(setarr: SetArray<T>): void;
/**
* Removes the key, if it exists in the set.
*/
export declare function remove<T extends Key>(setarr: SetArray<T>, key: T): void;
export {};
//# sourceMappingURL=set-array.d.ts.map

View File

@ -1 +0,0 @@
{"version":3,"file":"set-array.d.ts","sourceRoot":"","sources":["../src/set-array.ts"],"names":[],"mappings":"AAAA,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpC;;;;;;;GAOG;AACH,qBAAa,QAAQ,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG;IACvC,QAAgB,QAAQ,CAAgC;IAChD,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;;CAM7B;AAeD;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,GAAG,SAAS,CAElF;AAED;;;GAGG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,CAStE;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAM5D;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAYvE"}

View File

@ -1,33 +0,0 @@
type Key = string | number | symbol;
/**
* SetArray acts like a `Set` (allowing only one occurrence of a string `key`), but provides the
* index of the `key` in the backing array.
*
* This is designed to allow synchronizing a second array with the contents of the backing array,
* like how in a sourcemap `sourcesContent[i]` is the source content associated with `source[i]`,
* and there are never duplicates.
*/
export declare class SetArray<T extends Key = Key> {
private _indexes;
array: readonly T[];
constructor();
}
/**
* Gets the index associated with `key` in the backing array, if it is already present.
*/
export declare function get<T extends Key>(setarr: SetArray<T>, key: T): number | undefined;
/**
* Puts `key` into the backing array, if it is not already present. Returns
* the index of the `key` in the backing array.
*/
export declare function put<T extends Key>(setarr: SetArray<T>, key: T): number;
/**
* Pops the last added item out of the SetArray.
*/
export declare function pop<T extends Key>(setarr: SetArray<T>): void;
/**
* Removes the key, if it exists in the set.
*/
export declare function remove<T extends Key>(setarr: SetArray<T>, key: T): void;
export {};
//# sourceMappingURL=set-array.d.ts.map

View File

@ -1 +0,0 @@
{"version":3,"file":"set-array.d.ts","sourceRoot":"","sources":["../src/set-array.ts"],"names":[],"mappings":"AAAA,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpC;;;;;;;GAOG;AACH,qBAAa,QAAQ,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG;IACvC,QAAgB,QAAQ,CAAgC;IAChD,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;;CAM7B;AAeD;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,GAAG,SAAS,CAElF;AAED;;;GAGG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,CAStE;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAM5D;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAYvE"}

View File

@ -1,13 +0,0 @@
type GeneratedColumn = number;
type SourcesIndex = number;
type SourceLine = number;
type SourceColumn = number;
type NamesIndex = number;
export type SourceMapSegment = [GeneratedColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex];
export declare const COLUMN = 0;
export declare const SOURCES_INDEX = 1;
export declare const SOURCE_LINE = 2;
export declare const SOURCE_COLUMN = 3;
export declare const NAMES_INDEX = 4;
export {};
//# sourceMappingURL=sourcemap-segment.d.ts.map

View File

@ -1 +0,0 @@
{"version":3,"file":"sourcemap-segment.d.ts","sourceRoot":"","sources":["../src/sourcemap-segment.ts"],"names":[],"mappings":"AAAA,KAAK,eAAe,GAAG,MAAM,CAAC;AAC9B,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,UAAU,GAAG,MAAM,CAAC;AACzB,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,UAAU,GAAG,MAAM,CAAC;AAEzB,MAAM,MAAM,gBAAgB,GACxB,CAAC,eAAe,CAAC,GACjB,CAAC,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC,GACzD,CAAC,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;AAE1E,eAAO,MAAM,MAAM,IAAI,CAAC;AACxB,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,WAAW,IAAI,CAAC"}

View File

@ -1,13 +0,0 @@
type GeneratedColumn = number;
type SourcesIndex = number;
type SourceLine = number;
type SourceColumn = number;
type NamesIndex = number;
export type SourceMapSegment = [GeneratedColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex];
export declare const COLUMN = 0;
export declare const SOURCES_INDEX = 1;
export declare const SOURCE_LINE = 2;
export declare const SOURCE_COLUMN = 3;
export declare const NAMES_INDEX = 4;
export {};
//# sourceMappingURL=sourcemap-segment.d.ts.map

View File

@ -1 +0,0 @@
{"version":3,"file":"sourcemap-segment.d.ts","sourceRoot":"","sources":["../src/sourcemap-segment.ts"],"names":[],"mappings":"AAAA,KAAK,eAAe,GAAG,MAAM,CAAC;AAC9B,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,UAAU,GAAG,MAAM,CAAC;AACzB,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,UAAU,GAAG,MAAM,CAAC;AAEzB,MAAM,MAAM,gBAAgB,GACxB,CAAC,eAAe,CAAC,GACjB,CAAC,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC,GACzD,CAAC,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;AAE1E,eAAO,MAAM,MAAM,IAAI,CAAC;AACxB,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,WAAW,IAAI,CAAC"}

View File

@ -1,44 +0,0 @@
import type { SourceMapSegment } from './sourcemap-segment.cts';
export interface SourceMapV3 {
file?: string | null;
names: readonly string[];
sourceRoot?: string;
sources: readonly (string | null)[];
sourcesContent?: readonly (string | null)[];
version: 3;
ignoreList?: readonly number[];
}
export interface EncodedSourceMap extends SourceMapV3 {
mappings: string;
}
export interface DecodedSourceMap extends SourceMapV3 {
mappings: readonly SourceMapSegment[][];
}
export interface Pos {
line: number;
column: number;
}
export interface OriginalPos extends Pos {
source: string;
}
export interface BindingExpressionRange {
start: Pos;
expression: string;
}
export type Mapping = {
generated: Pos;
source: undefined;
original: undefined;
name: undefined;
} | {
generated: Pos;
source: string;
original: Pos;
name: string;
} | {
generated: Pos;
source: string;
original: Pos;
name: undefined;
};
//# sourceMappingURL=types.d.ts.map

View File

@ -1 +0,0 @@
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IACpC,cAAc,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAC5C,OAAO,EAAE,CAAC,CAAC;IACX,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,QAAQ,EAAE,MAAM,CAAC;CAGlB;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,QAAQ,EAAE,SAAS,gBAAgB,EAAE,EAAE,CAAC;CAGzC;AAED,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAY,SAAQ,GAAG;IACtC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,GAAG,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;CACpB;AAKD,MAAM,MAAM,OAAO,GACf;IACE,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;CACjB,GACD;IACE,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;CACjB,CAAC"}

View File

@ -1,44 +0,0 @@
import type { SourceMapSegment } from './sourcemap-segment.mts';
export interface SourceMapV3 {
file?: string | null;
names: readonly string[];
sourceRoot?: string;
sources: readonly (string | null)[];
sourcesContent?: readonly (string | null)[];
version: 3;
ignoreList?: readonly number[];
}
export interface EncodedSourceMap extends SourceMapV3 {
mappings: string;
}
export interface DecodedSourceMap extends SourceMapV3 {
mappings: readonly SourceMapSegment[][];
}
export interface Pos {
line: number;
column: number;
}
export interface OriginalPos extends Pos {
source: string;
}
export interface BindingExpressionRange {
start: Pos;
expression: string;
}
export type Mapping = {
generated: Pos;
source: undefined;
original: undefined;
name: undefined;
} | {
generated: Pos;
source: string;
original: Pos;
name: string;
} | {
generated: Pos;
source: string;
original: Pos;
name: undefined;
};
//# sourceMappingURL=types.d.ts.map

View File

@ -1 +0,0 @@
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IACpC,cAAc,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAC5C,OAAO,EAAE,CAAC,CAAC;IACX,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,QAAQ,EAAE,MAAM,CAAC;CAGlB;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,QAAQ,EAAE,SAAS,gBAAgB,EAAE,EAAE,CAAC;CAGzC;AAED,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAY,SAAQ,GAAG;IACtC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,GAAG,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;CACpB;AAKD,MAAM,MAAM,OAAO,GACf;IACE,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;CACjB,GACD;IACE,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;CACjB,CAAC"}

View File

@ -1,19 +0,0 @@
Copyright 2019 Justin Ridgewell <jridgewell@google.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,40 +0,0 @@
# @jridgewell/resolve-uri
> Resolve a URI relative to an optional base URI
Resolve any combination of absolute URIs, protocol-realtive URIs, absolute paths, or relative paths.
## Installation
```sh
npm install @jridgewell/resolve-uri
```
## Usage
```typescript
function resolve(input: string, base?: string): string;
```
```js
import resolve from '@jridgewell/resolve-uri';
resolve('foo', 'https://example.com'); // => 'https://example.com/foo'
```
| Input | Base | Resolution | Explanation |
|-----------------------|-------------------------|--------------------------------|--------------------------------------------------------------|
| `https://example.com` | _any_ | `https://example.com/` | Input is normalized only |
| `//example.com` | `https://base.com/` | `https://example.com/` | Input inherits the base's protocol |
| `//example.com` | _rest_ | `//example.com/` | Input is normalized only |
| `/example` | `https://base.com/` | `https://base.com/example` | Input inherits the base's origin |
| `/example` | `//base.com/` | `//base.com/example` | Input inherits the base's host and remains protocol relative |
| `/example` | _rest_ | `/example` | Input is normalized only |
| `example` | `https://base.com/dir/` | `https://base.com/dir/example` | Input is joined with the base |
| `example` | `https://base.com/file` | `https://base.com/example` | Input is joined with the base without its file |
| `example` | `//base.com/dir/` | `//base.com/dir/example` | Input is joined with the base's last directory |
| `example` | `//base.com/file` | `//base.com/example` | Input is joined with the base without its file |
| `example` | `/base/dir/` | `/base/dir/example` | Input is joined with the base's last directory |
| `example` | `/base/file` | `/base/example` | Input is joined with the base without its file |
| `example` | `base/dir/` | `base/dir/example` | Input is joined with the base's last directory |
| `example` | `base/file` | `base/example` | Input is joined with the base without its file |

View File

@ -1,69 +0,0 @@
{
"name": "@jridgewell/resolve-uri",
"version": "3.1.2",
"description": "Resolve a URI relative to an optional base URI",
"keywords": [
"resolve",
"uri",
"url",
"path"
],
"author": "Justin Ridgewell <justin@ridgewell.name>",
"license": "MIT",
"repository": "https://github.com/jridgewell/resolve-uri",
"main": "dist/resolve-uri.umd.js",
"module": "dist/resolve-uri.mjs",
"types": "dist/types/resolve-uri.d.ts",
"exports": {
".": [
{
"types": "./dist/types/resolve-uri.d.ts",
"browser": "./dist/resolve-uri.umd.js",
"require": "./dist/resolve-uri.umd.js",
"import": "./dist/resolve-uri.mjs"
},
"./dist/resolve-uri.umd.js"
],
"./package.json": "./package.json"
},
"files": [
"dist"
],
"engines": {
"node": ">=6.0.0"
},
"scripts": {
"prebuild": "rm -rf dist",
"build": "run-s -n build:*",
"build:rollup": "rollup -c rollup.config.js",
"build:ts": "tsc --project tsconfig.build.json",
"lint": "run-s -n lint:*",
"lint:prettier": "npm run test:lint:prettier -- --write",
"lint:ts": "npm run test:lint:ts -- --fix",
"pretest": "run-s build:rollup",
"test": "run-s -n test:lint test:only",
"test:debug": "mocha --inspect-brk",
"test:lint": "run-s -n test:lint:*",
"test:lint:prettier": "prettier --check '{src,test}/**/*.ts'",
"test:lint:ts": "eslint '{src,test}/**/*.ts'",
"test:only": "mocha",
"test:coverage": "c8 mocha",
"test:watch": "mocha --watch",
"prepublishOnly": "npm run preversion",
"preversion": "run-s test build"
},
"devDependencies": {
"@jridgewell/resolve-uri-latest": "npm:@jridgewell/resolve-uri@*",
"@rollup/plugin-typescript": "8.3.0",
"@typescript-eslint/eslint-plugin": "5.10.0",
"@typescript-eslint/parser": "5.10.0",
"c8": "7.11.0",
"eslint": "8.7.0",
"eslint-config-prettier": "8.3.0",
"mocha": "9.2.0",
"npm-run-all": "4.1.5",
"prettier": "2.5.1",
"rollup": "2.66.0",
"typescript": "4.5.5"
}
}

View File

@ -1,19 +0,0 @@
Copyright 2024 Justin Ridgewell <justin@ridgewell.name>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,264 +0,0 @@
# @jridgewell/sourcemap-codec
Encode/decode the `mappings` property of a [sourcemap](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit).
## Why?
Sourcemaps are difficult to generate and manipulate, because the `mappings` property the part that actually links the generated code back to the original source is encoded using an obscure method called [Variable-length quantity](https://en.wikipedia.org/wiki/Variable-length_quantity). On top of that, each segment in the mapping contains offsets rather than absolute indices, which means that you can't look at a segment in isolation you have to understand the whole sourcemap.
This package makes the process slightly easier.
## Installation
```bash
npm install @jridgewell/sourcemap-codec
```
## Usage
```js
import { encode, decode } from '@jridgewell/sourcemap-codec';
var decoded = decode( ';EAEEA,EAAE,EAAC,CAAE;ECQY,UACC' );
assert.deepEqual( decoded, [
// the first line (of the generated code) has no mappings,
// as shown by the starting semi-colon (which separates lines)
[],
// the second line contains four (comma-separated) segments
[
// segments are encoded as you'd expect:
// [ generatedCodeColumn, sourceIndex, sourceCodeLine, sourceCodeColumn, nameIndex ]
// i.e. the first segment begins at column 2, and maps back to the second column
// of the second line (both zero-based) of the 0th source, and uses the 0th
// name in the `map.names` array
[ 2, 0, 2, 2, 0 ],
// the remaining segments are 4-length rather than 5-length,
// because they don't map a name
[ 4, 0, 2, 4 ],
[ 6, 0, 2, 5 ],
[ 7, 0, 2, 7 ]
],
// the final line contains two segments
[
[ 2, 1, 10, 19 ],
[ 12, 1, 11, 20 ]
]
]);
var encoded = encode( decoded );
assert.equal( encoded, ';EAEEA,EAAE,EAAC,CAAE;ECQY,UACC' );
```
## Benchmarks
```
node v20.10.0
amp.js.map - 45120 segments
Decode Memory Usage:
local code 5815135 bytes
@jridgewell/sourcemap-codec 1.4.15 5868160 bytes
sourcemap-codec 5492584 bytes
source-map-0.6.1 13569984 bytes
source-map-0.8.0 6390584 bytes
chrome dev tools 8011136 bytes
Smallest memory usage is sourcemap-codec
Decode speed:
decode: local code x 492 ops/sec ±1.22% (90 runs sampled)
decode: @jridgewell/sourcemap-codec 1.4.15 x 499 ops/sec ±1.16% (89 runs sampled)
decode: sourcemap-codec x 376 ops/sec ±1.66% (89 runs sampled)
decode: source-map-0.6.1 x 34.99 ops/sec ±0.94% (48 runs sampled)
decode: source-map-0.8.0 x 351 ops/sec ±0.07% (95 runs sampled)
chrome dev tools x 165 ops/sec ±0.91% (86 runs sampled)
Fastest is decode: @jridgewell/sourcemap-codec 1.4.15
Encode Memory Usage:
local code 444248 bytes
@jridgewell/sourcemap-codec 1.4.15 623024 bytes
sourcemap-codec 8696280 bytes
source-map-0.6.1 8745176 bytes
source-map-0.8.0 8736624 bytes
Smallest memory usage is local code
Encode speed:
encode: local code x 796 ops/sec ±0.11% (97 runs sampled)
encode: @jridgewell/sourcemap-codec 1.4.15 x 795 ops/sec ±0.25% (98 runs sampled)
encode: sourcemap-codec x 231 ops/sec ±0.83% (86 runs sampled)
encode: source-map-0.6.1 x 166 ops/sec ±0.57% (86 runs sampled)
encode: source-map-0.8.0 x 203 ops/sec ±0.45% (88 runs sampled)
Fastest is encode: local code,encode: @jridgewell/sourcemap-codec 1.4.15
***
babel.min.js.map - 347793 segments
Decode Memory Usage:
local code 35424960 bytes
@jridgewell/sourcemap-codec 1.4.15 35424696 bytes
sourcemap-codec 36033464 bytes
source-map-0.6.1 62253704 bytes
source-map-0.8.0 43843920 bytes
chrome dev tools 45111400 bytes
Smallest memory usage is @jridgewell/sourcemap-codec 1.4.15
Decode speed:
decode: local code x 38.18 ops/sec ±5.44% (52 runs sampled)
decode: @jridgewell/sourcemap-codec 1.4.15 x 38.36 ops/sec ±5.02% (52 runs sampled)
decode: sourcemap-codec x 34.05 ops/sec ±4.45% (47 runs sampled)
decode: source-map-0.6.1 x 4.31 ops/sec ±2.76% (15 runs sampled)
decode: source-map-0.8.0 x 55.60 ops/sec ±0.13% (73 runs sampled)
chrome dev tools x 16.94 ops/sec ±3.78% (46 runs sampled)
Fastest is decode: source-map-0.8.0
Encode Memory Usage:
local code 2606016 bytes
@jridgewell/sourcemap-codec 1.4.15 2626440 bytes
sourcemap-codec 21152576 bytes
source-map-0.6.1 25023928 bytes
source-map-0.8.0 25256448 bytes
Smallest memory usage is local code
Encode speed:
encode: local code x 127 ops/sec ±0.18% (83 runs sampled)
encode: @jridgewell/sourcemap-codec 1.4.15 x 128 ops/sec ±0.26% (83 runs sampled)
encode: sourcemap-codec x 29.31 ops/sec ±2.55% (53 runs sampled)
encode: source-map-0.6.1 x 18.85 ops/sec ±3.19% (36 runs sampled)
encode: source-map-0.8.0 x 19.34 ops/sec ±1.97% (36 runs sampled)
Fastest is encode: @jridgewell/sourcemap-codec 1.4.15
***
preact.js.map - 1992 segments
Decode Memory Usage:
local code 261696 bytes
@jridgewell/sourcemap-codec 1.4.15 244296 bytes
sourcemap-codec 302816 bytes
source-map-0.6.1 939176 bytes
source-map-0.8.0 336 bytes
chrome dev tools 587368 bytes
Smallest memory usage is source-map-0.8.0
Decode speed:
decode: local code x 17,782 ops/sec ±0.32% (97 runs sampled)
decode: @jridgewell/sourcemap-codec 1.4.15 x 17,863 ops/sec ±0.40% (100 runs sampled)
decode: sourcemap-codec x 12,453 ops/sec ±0.27% (101 runs sampled)
decode: source-map-0.6.1 x 1,288 ops/sec ±1.05% (96 runs sampled)
decode: source-map-0.8.0 x 9,289 ops/sec ±0.27% (101 runs sampled)
chrome dev tools x 4,769 ops/sec ±0.18% (100 runs sampled)
Fastest is decode: @jridgewell/sourcemap-codec 1.4.15
Encode Memory Usage:
local code 262944 bytes
@jridgewell/sourcemap-codec 1.4.15 25544 bytes
sourcemap-codec 323048 bytes
source-map-0.6.1 507808 bytes
source-map-0.8.0 507480 bytes
Smallest memory usage is @jridgewell/sourcemap-codec 1.4.15
Encode speed:
encode: local code x 24,207 ops/sec ±0.79% (95 runs sampled)
encode: @jridgewell/sourcemap-codec 1.4.15 x 24,288 ops/sec ±0.48% (96 runs sampled)
encode: sourcemap-codec x 6,761 ops/sec ±0.21% (100 runs sampled)
encode: source-map-0.6.1 x 5,374 ops/sec ±0.17% (99 runs sampled)
encode: source-map-0.8.0 x 5,633 ops/sec ±0.32% (99 runs sampled)
Fastest is encode: @jridgewell/sourcemap-codec 1.4.15,encode: local code
***
react.js.map - 5726 segments
Decode Memory Usage:
local code 678816 bytes
@jridgewell/sourcemap-codec 1.4.15 678816 bytes
sourcemap-codec 816400 bytes
source-map-0.6.1 2288864 bytes
source-map-0.8.0 721360 bytes
chrome dev tools 1012512 bytes
Smallest memory usage is local code
Decode speed:
decode: local code x 6,178 ops/sec ±0.19% (98 runs sampled)
decode: @jridgewell/sourcemap-codec 1.4.15 x 6,261 ops/sec ±0.22% (100 runs sampled)
decode: sourcemap-codec x 4,472 ops/sec ±0.90% (99 runs sampled)
decode: source-map-0.6.1 x 449 ops/sec ±0.31% (95 runs sampled)
decode: source-map-0.8.0 x 3,219 ops/sec ±0.13% (100 runs sampled)
chrome dev tools x 1,743 ops/sec ±0.20% (99 runs sampled)
Fastest is decode: @jridgewell/sourcemap-codec 1.4.15
Encode Memory Usage:
local code 140960 bytes
@jridgewell/sourcemap-codec 1.4.15 159808 bytes
sourcemap-codec 969304 bytes
source-map-0.6.1 930520 bytes
source-map-0.8.0 930248 bytes
Smallest memory usage is local code
Encode speed:
encode: local code x 8,013 ops/sec ±0.19% (100 runs sampled)
encode: @jridgewell/sourcemap-codec 1.4.15 x 7,989 ops/sec ±0.20% (101 runs sampled)
encode: sourcemap-codec x 2,472 ops/sec ±0.21% (99 runs sampled)
encode: source-map-0.6.1 x 2,200 ops/sec ±0.17% (99 runs sampled)
encode: source-map-0.8.0 x 2,220 ops/sec ±0.37% (99 runs sampled)
Fastest is encode: local code
***
vscode.map - 2141001 segments
Decode Memory Usage:
local code 198955264 bytes
@jridgewell/sourcemap-codec 1.4.15 199175352 bytes
sourcemap-codec 199102688 bytes
source-map-0.6.1 386323432 bytes
source-map-0.8.0 244116432 bytes
chrome dev tools 293734280 bytes
Smallest memory usage is local code
Decode speed:
decode: local code x 3.90 ops/sec ±22.21% (15 runs sampled)
decode: @jridgewell/sourcemap-codec 1.4.15 x 3.95 ops/sec ±23.53% (15 runs sampled)
decode: sourcemap-codec x 3.82 ops/sec ±17.94% (14 runs sampled)
decode: source-map-0.6.1 x 0.61 ops/sec ±7.81% (6 runs sampled)
decode: source-map-0.8.0 x 9.54 ops/sec ±0.28% (28 runs sampled)
chrome dev tools x 2.18 ops/sec ±10.58% (10 runs sampled)
Fastest is decode: source-map-0.8.0
Encode Memory Usage:
local code 13509880 bytes
@jridgewell/sourcemap-codec 1.4.15 13537648 bytes
sourcemap-codec 32540104 bytes
source-map-0.6.1 127531040 bytes
source-map-0.8.0 127535312 bytes
Smallest memory usage is local code
Encode speed:
encode: local code x 20.10 ops/sec ±0.19% (38 runs sampled)
encode: @jridgewell/sourcemap-codec 1.4.15 x 20.26 ops/sec ±0.32% (38 runs sampled)
encode: sourcemap-codec x 5.44 ops/sec ±1.64% (18 runs sampled)
encode: source-map-0.6.1 x 2.30 ops/sec ±4.79% (10 runs sampled)
encode: source-map-0.8.0 x 2.46 ops/sec ±6.53% (10 runs sampled)
Fastest is encode: @jridgewell/sourcemap-codec 1.4.15
```
# License
MIT

View File

@ -1,63 +0,0 @@
{
"name": "@jridgewell/sourcemap-codec",
"version": "1.5.5",
"description": "Encode/decode sourcemap mappings",
"keywords": [
"sourcemap",
"vlq"
],
"main": "dist/sourcemap-codec.umd.js",
"module": "dist/sourcemap-codec.mjs",
"types": "types/sourcemap-codec.d.cts",
"files": [
"dist",
"src",
"types"
],
"exports": {
".": [
{
"import": {
"types": "./types/sourcemap-codec.d.mts",
"default": "./dist/sourcemap-codec.mjs"
},
"default": {
"types": "./types/sourcemap-codec.d.cts",
"default": "./dist/sourcemap-codec.umd.js"
}
},
"./dist/sourcemap-codec.umd.js"
],
"./package.json": "./package.json"
},
"scripts": {
"benchmark": "run-s build:code benchmark:*",
"benchmark:install": "cd benchmark && npm install",
"benchmark:only": "node --expose-gc benchmark/index.js",
"build": "run-s -n build:code build:types",
"build:code": "node ../../esbuild.mjs sourcemap-codec.ts",
"build:types": "run-s build:types:force build:types:emit build:types:mts",
"build:types:force": "rimraf tsconfig.build.tsbuildinfo",
"build:types:emit": "tsc --project tsconfig.build.json",
"build:types:mts": "node ../../mts-types.mjs",
"clean": "run-s -n clean:code clean:types",
"clean:code": "tsc --build --clean tsconfig.build.json",
"clean:types": "rimraf dist types",
"test": "run-s -n test:types test:only test:format",
"test:format": "prettier --check '{src,test}/**/*.ts'",
"test:only": "mocha",
"test:types": "eslint '{src,test}/**/*.ts'",
"lint": "run-s -n lint:types lint:format",
"lint:format": "npm run test:format -- --write",
"lint:types": "npm run test:types -- --fix",
"prepublishOnly": "npm run-s -n build test"
},
"homepage": "https://github.com/jridgewell/sourcemaps/tree/main/packages/sourcemap-codec",
"repository": {
"type": "git",
"url": "git+https://github.com/jridgewell/sourcemaps.git",
"directory": "packages/sourcemap-codec"
},
"author": "Justin Ridgewell <justin@ridgewell.name>",
"license": "MIT"
}

View File

@ -1,345 +0,0 @@
import { StringReader, StringWriter } from './strings';
import { comma, decodeInteger, encodeInteger, hasMoreVlq, semicolon } from './vlq';
const EMPTY: any[] = [];
type Line = number;
type Column = number;
type Kind = number;
type Name = number;
type Var = number;
type SourcesIndex = number;
type ScopesIndex = number;
type Mix<A, B, O> = (A & O) | (B & O);
export type OriginalScope = Mix<
[Line, Column, Line, Column, Kind],
[Line, Column, Line, Column, Kind, Name],
{ vars: Var[] }
>;
export type GeneratedRange = Mix<
[Line, Column, Line, Column],
[Line, Column, Line, Column, SourcesIndex, ScopesIndex],
{
callsite: CallSite | null;
bindings: Binding[];
isScope: boolean;
}
>;
export type CallSite = [SourcesIndex, Line, Column];
type Binding = BindingExpressionRange[];
export type BindingExpressionRange = [Name] | [Name, Line, Column];
export function decodeOriginalScopes(input: string): OriginalScope[] {
const { length } = input;
const reader = new StringReader(input);
const scopes: OriginalScope[] = [];
const stack: OriginalScope[] = [];
let line = 0;
for (; reader.pos < length; reader.pos++) {
line = decodeInteger(reader, line);
const column = decodeInteger(reader, 0);
if (!hasMoreVlq(reader, length)) {
const last = stack.pop()!;
last[2] = line;
last[3] = column;
continue;
}
const kind = decodeInteger(reader, 0);
const fields = decodeInteger(reader, 0);
const hasName = fields & 0b0001;
const scope: OriginalScope = (
hasName ? [line, column, 0, 0, kind, decodeInteger(reader, 0)] : [line, column, 0, 0, kind]
) as OriginalScope;
let vars: Var[] = EMPTY;
if (hasMoreVlq(reader, length)) {
vars = [];
do {
const varsIndex = decodeInteger(reader, 0);
vars.push(varsIndex);
} while (hasMoreVlq(reader, length));
}
scope.vars = vars;
scopes.push(scope);
stack.push(scope);
}
return scopes;
}
export function encodeOriginalScopes(scopes: OriginalScope[]): string {
const writer = new StringWriter();
for (let i = 0; i < scopes.length; ) {
i = _encodeOriginalScopes(scopes, i, writer, [0]);
}
return writer.flush();
}
function _encodeOriginalScopes(
scopes: OriginalScope[],
index: number,
writer: StringWriter,
state: [
number, // GenColumn
],
): number {
const scope = scopes[index];
const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, 4: kind, vars } = scope;
if (index > 0) writer.write(comma);
state[0] = encodeInteger(writer, startLine, state[0]);
encodeInteger(writer, startColumn, 0);
encodeInteger(writer, kind, 0);
const fields = scope.length === 6 ? 0b0001 : 0;
encodeInteger(writer, fields, 0);
if (scope.length === 6) encodeInteger(writer, scope[5], 0);
for (const v of vars) {
encodeInteger(writer, v, 0);
}
for (index++; index < scopes.length; ) {
const next = scopes[index];
const { 0: l, 1: c } = next;
if (l > endLine || (l === endLine && c >= endColumn)) {
break;
}
index = _encodeOriginalScopes(scopes, index, writer, state);
}
writer.write(comma);
state[0] = encodeInteger(writer, endLine, state[0]);
encodeInteger(writer, endColumn, 0);
return index;
}
export function decodeGeneratedRanges(input: string): GeneratedRange[] {
const { length } = input;
const reader = new StringReader(input);
const ranges: GeneratedRange[] = [];
const stack: GeneratedRange[] = [];
let genLine = 0;
let definitionSourcesIndex = 0;
let definitionScopeIndex = 0;
let callsiteSourcesIndex = 0;
let callsiteLine = 0;
let callsiteColumn = 0;
let bindingLine = 0;
let bindingColumn = 0;
do {
const semi = reader.indexOf(';');
let genColumn = 0;
for (; reader.pos < semi; reader.pos++) {
genColumn = decodeInteger(reader, genColumn);
if (!hasMoreVlq(reader, semi)) {
const last = stack.pop()!;
last[2] = genLine;
last[3] = genColumn;
continue;
}
const fields = decodeInteger(reader, 0);
const hasDefinition = fields & 0b0001;
const hasCallsite = fields & 0b0010;
const hasScope = fields & 0b0100;
let callsite: CallSite | null = null;
let bindings: Binding[] = EMPTY;
let range: GeneratedRange;
if (hasDefinition) {
const defSourcesIndex = decodeInteger(reader, definitionSourcesIndex);
definitionScopeIndex = decodeInteger(
reader,
definitionSourcesIndex === defSourcesIndex ? definitionScopeIndex : 0,
);
definitionSourcesIndex = defSourcesIndex;
range = [genLine, genColumn, 0, 0, defSourcesIndex, definitionScopeIndex] as GeneratedRange;
} else {
range = [genLine, genColumn, 0, 0] as GeneratedRange;
}
range.isScope = !!hasScope;
if (hasCallsite) {
const prevCsi = callsiteSourcesIndex;
const prevLine = callsiteLine;
callsiteSourcesIndex = decodeInteger(reader, callsiteSourcesIndex);
const sameSource = prevCsi === callsiteSourcesIndex;
callsiteLine = decodeInteger(reader, sameSource ? callsiteLine : 0);
callsiteColumn = decodeInteger(
reader,
sameSource && prevLine === callsiteLine ? callsiteColumn : 0,
);
callsite = [callsiteSourcesIndex, callsiteLine, callsiteColumn];
}
range.callsite = callsite;
if (hasMoreVlq(reader, semi)) {
bindings = [];
do {
bindingLine = genLine;
bindingColumn = genColumn;
const expressionsCount = decodeInteger(reader, 0);
let expressionRanges: BindingExpressionRange[];
if (expressionsCount < -1) {
expressionRanges = [[decodeInteger(reader, 0)]];
for (let i = -1; i > expressionsCount; i--) {
const prevBl = bindingLine;
bindingLine = decodeInteger(reader, bindingLine);
bindingColumn = decodeInteger(reader, bindingLine === prevBl ? bindingColumn : 0);
const expression = decodeInteger(reader, 0);
expressionRanges.push([expression, bindingLine, bindingColumn]);
}
} else {
expressionRanges = [[expressionsCount]];
}
bindings.push(expressionRanges);
} while (hasMoreVlq(reader, semi));
}
range.bindings = bindings;
ranges.push(range);
stack.push(range);
}
genLine++;
reader.pos = semi + 1;
} while (reader.pos < length);
return ranges;
}
export function encodeGeneratedRanges(ranges: GeneratedRange[]): string {
if (ranges.length === 0) return '';
const writer = new StringWriter();
for (let i = 0; i < ranges.length; ) {
i = _encodeGeneratedRanges(ranges, i, writer, [0, 0, 0, 0, 0, 0, 0]);
}
return writer.flush();
}
function _encodeGeneratedRanges(
ranges: GeneratedRange[],
index: number,
writer: StringWriter,
state: [
number, // GenLine
number, // GenColumn
number, // DefSourcesIndex
number, // DefScopesIndex
number, // CallSourcesIndex
number, // CallLine
number, // CallColumn
],
): number {
const range = ranges[index];
const {
0: startLine,
1: startColumn,
2: endLine,
3: endColumn,
isScope,
callsite,
bindings,
} = range;
if (state[0] < startLine) {
catchupLine(writer, state[0], startLine);
state[0] = startLine;
state[1] = 0;
} else if (index > 0) {
writer.write(comma);
}
state[1] = encodeInteger(writer, range[1], state[1]);
const fields =
(range.length === 6 ? 0b0001 : 0) | (callsite ? 0b0010 : 0) | (isScope ? 0b0100 : 0);
encodeInteger(writer, fields, 0);
if (range.length === 6) {
const { 4: sourcesIndex, 5: scopesIndex } = range;
if (sourcesIndex !== state[2]) {
state[3] = 0;
}
state[2] = encodeInteger(writer, sourcesIndex, state[2]);
state[3] = encodeInteger(writer, scopesIndex, state[3]);
}
if (callsite) {
const { 0: sourcesIndex, 1: callLine, 2: callColumn } = range.callsite!;
if (sourcesIndex !== state[4]) {
state[5] = 0;
state[6] = 0;
} else if (callLine !== state[5]) {
state[6] = 0;
}
state[4] = encodeInteger(writer, sourcesIndex, state[4]);
state[5] = encodeInteger(writer, callLine, state[5]);
state[6] = encodeInteger(writer, callColumn, state[6]);
}
if (bindings) {
for (const binding of bindings) {
if (binding.length > 1) encodeInteger(writer, -binding.length, 0);
const expression = binding[0][0];
encodeInteger(writer, expression, 0);
let bindingStartLine = startLine;
let bindingStartColumn = startColumn;
for (let i = 1; i < binding.length; i++) {
const expRange = binding[i];
bindingStartLine = encodeInteger(writer, expRange[1]!, bindingStartLine);
bindingStartColumn = encodeInteger(writer, expRange[2]!, bindingStartColumn);
encodeInteger(writer, expRange[0]!, 0);
}
}
}
for (index++; index < ranges.length; ) {
const next = ranges[index];
const { 0: l, 1: c } = next;
if (l > endLine || (l === endLine && c >= endColumn)) {
break;
}
index = _encodeGeneratedRanges(ranges, index, writer, state);
}
if (state[0] < endLine) {
catchupLine(writer, state[0], endLine);
state[0] = endLine;
state[1] = 0;
} else {
writer.write(comma);
}
state[1] = encodeInteger(writer, endColumn, state[1]);
return index;
}
function catchupLine(writer: StringWriter, lastLine: number, line: number) {
do {
writer.write(semicolon);
} while (++lastLine < line);
}

View File

@ -1,111 +0,0 @@
import { comma, decodeInteger, encodeInteger, hasMoreVlq, semicolon } from './vlq';
import { StringWriter, StringReader } from './strings';
export {
decodeOriginalScopes,
encodeOriginalScopes,
decodeGeneratedRanges,
encodeGeneratedRanges,
} from './scopes';
export type { OriginalScope, GeneratedRange, CallSite, BindingExpressionRange } from './scopes';
export type SourceMapSegment =
| [number]
| [number, number, number, number]
| [number, number, number, number, number];
export type SourceMapLine = SourceMapSegment[];
export type SourceMapMappings = SourceMapLine[];
export function decode(mappings: string): SourceMapMappings {
const { length } = mappings;
const reader = new StringReader(mappings);
const decoded: SourceMapMappings = [];
let genColumn = 0;
let sourcesIndex = 0;
let sourceLine = 0;
let sourceColumn = 0;
let namesIndex = 0;
do {
const semi = reader.indexOf(';');
const line: SourceMapLine = [];
let sorted = true;
let lastCol = 0;
genColumn = 0;
while (reader.pos < semi) {
let seg: SourceMapSegment;
genColumn = decodeInteger(reader, genColumn);
if (genColumn < lastCol) sorted = false;
lastCol = genColumn;
if (hasMoreVlq(reader, semi)) {
sourcesIndex = decodeInteger(reader, sourcesIndex);
sourceLine = decodeInteger(reader, sourceLine);
sourceColumn = decodeInteger(reader, sourceColumn);
if (hasMoreVlq(reader, semi)) {
namesIndex = decodeInteger(reader, namesIndex);
seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex];
} else {
seg = [genColumn, sourcesIndex, sourceLine, sourceColumn];
}
} else {
seg = [genColumn];
}
line.push(seg);
reader.pos++;
}
if (!sorted) sort(line);
decoded.push(line);
reader.pos = semi + 1;
} while (reader.pos <= length);
return decoded;
}
function sort(line: SourceMapSegment[]) {
line.sort(sortComparator);
}
function sortComparator(a: SourceMapSegment, b: SourceMapSegment): number {
return a[0] - b[0];
}
export function encode(decoded: SourceMapMappings): string;
export function encode(decoded: Readonly<SourceMapMappings>): string;
export function encode(decoded: Readonly<SourceMapMappings>): string {
const writer = new StringWriter();
let sourcesIndex = 0;
let sourceLine = 0;
let sourceColumn = 0;
let namesIndex = 0;
for (let i = 0; i < decoded.length; i++) {
const line = decoded[i];
if (i > 0) writer.write(semicolon);
if (line.length === 0) continue;
let genColumn = 0;
for (let j = 0; j < line.length; j++) {
const segment = line[j];
if (j > 0) writer.write(comma);
genColumn = encodeInteger(writer, segment[0], genColumn);
if (segment.length === 1) continue;
sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex);
sourceLine = encodeInteger(writer, segment[2], sourceLine);
sourceColumn = encodeInteger(writer, segment[3], sourceColumn);
if (segment.length === 4) continue;
namesIndex = encodeInteger(writer, segment[4], namesIndex);
}
}
return writer.flush();
}

View File

@ -1,65 +0,0 @@
const bufLength = 1024 * 16;
// Provide a fallback for older environments.
const td =
typeof TextDecoder !== 'undefined'
? /* #__PURE__ */ new TextDecoder()
: typeof Buffer !== 'undefined'
? {
decode(buf: Uint8Array): string {
const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength);
return out.toString();
},
}
: {
decode(buf: Uint8Array): string {
let out = '';
for (let i = 0; i < buf.length; i++) {
out += String.fromCharCode(buf[i]);
}
return out;
},
};
export class StringWriter {
pos = 0;
private out = '';
private buffer = new Uint8Array(bufLength);
write(v: number): void {
const { buffer } = this;
buffer[this.pos++] = v;
if (this.pos === bufLength) {
this.out += td.decode(buffer);
this.pos = 0;
}
}
flush(): string {
const { buffer, out, pos } = this;
return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out;
}
}
export class StringReader {
pos = 0;
declare private buffer: string;
constructor(buffer: string) {
this.buffer = buffer;
}
next(): number {
return this.buffer.charCodeAt(this.pos++);
}
peek(): number {
return this.buffer.charCodeAt(this.pos);
}
indexOf(char: string): number {
const { buffer, pos } = this;
const idx = buffer.indexOf(char, pos);
return idx === -1 ? buffer.length : idx;
}
}

View File

@ -1,55 +0,0 @@
import type { StringReader, StringWriter } from './strings';
export const comma = ','.charCodeAt(0);
export const semicolon = ';'.charCodeAt(0);
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
const intToChar = new Uint8Array(64); // 64 possible chars.
const charToInt = new Uint8Array(128); // z is 122 in ASCII
for (let i = 0; i < chars.length; i++) {
const c = chars.charCodeAt(i);
intToChar[i] = c;
charToInt[c] = i;
}
export function decodeInteger(reader: StringReader, relative: number): number {
let value = 0;
let shift = 0;
let integer = 0;
do {
const c = reader.next();
integer = charToInt[c];
value |= (integer & 31) << shift;
shift += 5;
} while (integer & 32);
const shouldNegate = value & 1;
value >>>= 1;
if (shouldNegate) {
value = -0x80000000 | -value;
}
return relative + value;
}
export function encodeInteger(builder: StringWriter, num: number, relative: number): number {
let delta = num - relative;
delta = delta < 0 ? (-delta << 1) | 1 : delta << 1;
do {
let clamped = delta & 0b011111;
delta >>>= 5;
if (delta > 0) clamped |= 0b100000;
builder.write(intToChar[clamped]);
} while (delta > 0);
return num;
}
export function hasMoreVlq(reader: StringReader, max: number) {
if (reader.pos >= max) return false;
return reader.peek() !== comma;
}

View File

@ -1,50 +0,0 @@
type Line = number;
type Column = number;
type Kind = number;
type Name = number;
type Var = number;
type SourcesIndex = number;
type ScopesIndex = number;
type Mix<A, B, O> = (A & O) | (B & O);
export type OriginalScope = Mix<[
Line,
Column,
Line,
Column,
Kind
], [
Line,
Column,
Line,
Column,
Kind,
Name
], {
vars: Var[];
}>;
export type GeneratedRange = Mix<[
Line,
Column,
Line,
Column
], [
Line,
Column,
Line,
Column,
SourcesIndex,
ScopesIndex
], {
callsite: CallSite | null;
bindings: Binding[];
isScope: boolean;
}>;
export type CallSite = [SourcesIndex, Line, Column];
type Binding = BindingExpressionRange[];
export type BindingExpressionRange = [Name] | [Name, Line, Column];
export declare function decodeOriginalScopes(input: string): OriginalScope[];
export declare function encodeOriginalScopes(scopes: OriginalScope[]): string;
export declare function decodeGeneratedRanges(input: string): GeneratedRange[];
export declare function encodeGeneratedRanges(ranges: GeneratedRange[]): string;
export {};
//# sourceMappingURL=scopes.d.ts.map

View File

@ -1 +0,0 @@
{"version":3,"file":"scopes.d.ts","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAKA,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,MAAM,GAAG,MAAM,CAAC;AACrB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,GAAG,GAAG,MAAM,CAAC;AAClB,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,WAAW,GAAG,MAAM,CAAC;AAE1B,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG,GAAG,CAC7B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;CAAC,EAClC;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,IAAI;CAAC,EACxC;IAAE,IAAI,EAAE,GAAG,EAAE,CAAA;CAAE,CAChB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,GAAG,CAC9B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;CAAC,EAC5B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,YAAY;IAAE,WAAW;CAAC,EACvD;IACE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB,CACF,CAAC;AACF,MAAM,MAAM,QAAQ,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AACpD,KAAK,OAAO,GAAG,sBAAsB,EAAE,CAAC;AACxC,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAEnE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,EAAE,CAyCnE;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAQpE;AA2CD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAoGrE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,CAUtE"}

View File

@ -1,50 +0,0 @@
type Line = number;
type Column = number;
type Kind = number;
type Name = number;
type Var = number;
type SourcesIndex = number;
type ScopesIndex = number;
type Mix<A, B, O> = (A & O) | (B & O);
export type OriginalScope = Mix<[
Line,
Column,
Line,
Column,
Kind
], [
Line,
Column,
Line,
Column,
Kind,
Name
], {
vars: Var[];
}>;
export type GeneratedRange = Mix<[
Line,
Column,
Line,
Column
], [
Line,
Column,
Line,
Column,
SourcesIndex,
ScopesIndex
], {
callsite: CallSite | null;
bindings: Binding[];
isScope: boolean;
}>;
export type CallSite = [SourcesIndex, Line, Column];
type Binding = BindingExpressionRange[];
export type BindingExpressionRange = [Name] | [Name, Line, Column];
export declare function decodeOriginalScopes(input: string): OriginalScope[];
export declare function encodeOriginalScopes(scopes: OriginalScope[]): string;
export declare function decodeGeneratedRanges(input: string): GeneratedRange[];
export declare function encodeGeneratedRanges(ranges: GeneratedRange[]): string;
export {};
//# sourceMappingURL=scopes.d.ts.map

View File

@ -1 +0,0 @@
{"version":3,"file":"scopes.d.ts","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAKA,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,MAAM,GAAG,MAAM,CAAC;AACrB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,GAAG,GAAG,MAAM,CAAC;AAClB,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,WAAW,GAAG,MAAM,CAAC;AAE1B,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG,GAAG,CAC7B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;CAAC,EAClC;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,IAAI;CAAC,EACxC;IAAE,IAAI,EAAE,GAAG,EAAE,CAAA;CAAE,CAChB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,GAAG,CAC9B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;CAAC,EAC5B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,YAAY;IAAE,WAAW;CAAC,EACvD;IACE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB,CACF,CAAC;AACF,MAAM,MAAM,QAAQ,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AACpD,KAAK,OAAO,GAAG,sBAAsB,EAAE,CAAC;AACxC,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAEnE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,EAAE,CAyCnE;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAQpE;AA2CD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAoGrE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,CAUtE"}

View File

@ -1,9 +0,0 @@
export { decodeOriginalScopes, encodeOriginalScopes, decodeGeneratedRanges, encodeGeneratedRanges, } from './scopes.cts';
export type { OriginalScope, GeneratedRange, CallSite, BindingExpressionRange } from './scopes.cts';
export type SourceMapSegment = [number] | [number, number, number, number] | [number, number, number, number, number];
export type SourceMapLine = SourceMapSegment[];
export type SourceMapMappings = SourceMapLine[];
export declare function decode(mappings: string): SourceMapMappings;
export declare function encode(decoded: SourceMapMappings): string;
export declare function encode(decoded: Readonly<SourceMapMappings>): string;
//# sourceMappingURL=sourcemap-codec.d.ts.map

View File

@ -1 +0,0 @@
{"version":3,"file":"sourcemap-codec.d.ts","sourceRoot":"","sources":["../src/sourcemap-codec.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEhG,MAAM,MAAM,gBAAgB,GACxB,CAAC,MAAM,CAAC,GACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAChC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAC7C,MAAM,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;AAC/C,MAAM,MAAM,iBAAiB,GAAG,aAAa,EAAE,CAAC;AAEhD,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAiD1D;AAUD,wBAAgB,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAAC;AAC3D,wBAAgB,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC"}

View File

@ -1,9 +0,0 @@
export { decodeOriginalScopes, encodeOriginalScopes, decodeGeneratedRanges, encodeGeneratedRanges, } from './scopes.mts';
export type { OriginalScope, GeneratedRange, CallSite, BindingExpressionRange } from './scopes.mts';
export type SourceMapSegment = [number] | [number, number, number, number] | [number, number, number, number, number];
export type SourceMapLine = SourceMapSegment[];
export type SourceMapMappings = SourceMapLine[];
export declare function decode(mappings: string): SourceMapMappings;
export declare function encode(decoded: SourceMapMappings): string;
export declare function encode(decoded: Readonly<SourceMapMappings>): string;
//# sourceMappingURL=sourcemap-codec.d.ts.map

View File

@ -1 +0,0 @@
{"version":3,"file":"sourcemap-codec.d.ts","sourceRoot":"","sources":["../src/sourcemap-codec.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEhG,MAAM,MAAM,gBAAgB,GACxB,CAAC,MAAM,CAAC,GACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAChC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAC7C,MAAM,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;AAC/C,MAAM,MAAM,iBAAiB,GAAG,aAAa,EAAE,CAAC;AAEhD,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAiD1D;AAUD,wBAAgB,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAAC;AAC3D,wBAAgB,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC"}

View File

@ -1,16 +0,0 @@
export declare class StringWriter {
pos: number;
private out;
private buffer;
write(v: number): void;
flush(): string;
}
export declare class StringReader {
pos: number;
private buffer;
constructor(buffer: string);
next(): number;
peek(): number;
indexOf(char: string): number;
}
//# sourceMappingURL=strings.d.ts.map

View File

@ -1 +0,0 @@
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../src/strings.ts"],"names":[],"mappings":"AAuBA,qBAAa,YAAY;IACvB,GAAG,SAAK;IACR,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,MAAM,CAA6B;IAE3C,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAStB,KAAK,IAAI,MAAM;CAIhB;AAED,qBAAa,YAAY;IACvB,GAAG,SAAK;IACR,QAAgB,MAAM,CAAS;gBAEnB,MAAM,EAAE,MAAM;IAI1B,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAId,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAK9B"}

View File

@ -1,16 +0,0 @@
export declare class StringWriter {
pos: number;
private out;
private buffer;
write(v: number): void;
flush(): string;
}
export declare class StringReader {
pos: number;
private buffer;
constructor(buffer: string);
next(): number;
peek(): number;
indexOf(char: string): number;
}
//# sourceMappingURL=strings.d.ts.map

View File

@ -1 +0,0 @@
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../src/strings.ts"],"names":[],"mappings":"AAuBA,qBAAa,YAAY;IACvB,GAAG,SAAK;IACR,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,MAAM,CAA6B;IAE3C,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAStB,KAAK,IAAI,MAAM;CAIhB;AAED,qBAAa,YAAY;IACvB,GAAG,SAAK;IACR,QAAgB,MAAM,CAAS;gBAEnB,MAAM,EAAE,MAAM;IAI1B,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAId,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAK9B"}

View File

@ -1,7 +0,0 @@
import type { StringReader, StringWriter } from './strings.cts';
export declare const comma: number;
export declare const semicolon: number;
export declare function decodeInteger(reader: StringReader, relative: number): number;
export declare function encodeInteger(builder: StringWriter, num: number, relative: number): number;
export declare function hasMoreVlq(reader: StringReader, max: number): boolean;
//# sourceMappingURL=vlq.d.ts.map

View File

@ -1 +0,0 @@
{"version":3,"file":"vlq.d.ts","sourceRoot":"","sources":["../src/vlq.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE5D,eAAO,MAAM,KAAK,QAAoB,CAAC;AACvC,eAAO,MAAM,SAAS,QAAoB,CAAC;AAY3C,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAoB5E;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAY1F;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,WAG3D"}

View File

@ -1,7 +0,0 @@
import type { StringReader, StringWriter } from './strings.mts';
export declare const comma: number;
export declare const semicolon: number;
export declare function decodeInteger(reader: StringReader, relative: number): number;
export declare function encodeInteger(builder: StringWriter, num: number, relative: number): number;
export declare function hasMoreVlq(reader: StringReader, max: number): boolean;
//# sourceMappingURL=vlq.d.ts.map

View File

@ -1 +0,0 @@
{"version":3,"file":"vlq.d.ts","sourceRoot":"","sources":["../src/vlq.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE5D,eAAO,MAAM,KAAK,QAAoB,CAAC;AACvC,eAAO,MAAM,SAAS,QAAoB,CAAC;AAY3C,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAoB5E;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAY1F;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,WAG3D"}

View File

@ -1,19 +0,0 @@
Copyright 2024 Justin Ridgewell <justin@ridgewell.name>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,348 +0,0 @@
# @jridgewell/trace-mapping
> Trace the original position through a source map
`trace-mapping` allows you to take the line and column of an output file and trace it to the
original location in the source file through a source map.
You may already be familiar with the [`source-map`][source-map] package's `SourceMapConsumer`. This
provides the same `originalPositionFor` and `generatedPositionFor` API, without requiring WASM.
## Installation
```sh
npm install @jridgewell/trace-mapping
```
## Usage
```typescript
import {
TraceMap,
originalPositionFor,
generatedPositionFor,
sourceContentFor,
isIgnored,
} from '@jridgewell/trace-mapping';
const tracer = new TraceMap({
version: 3,
sources: ['input.js'],
sourcesContent: ['content of input.js'],
names: ['foo'],
mappings: 'KAyCIA',
ignoreList: [],
});
// Lines start at line 1, columns at column 0.
const traced = originalPositionFor(tracer, { line: 1, column: 5 });
assert.deepEqual(traced, {
source: 'input.js',
line: 42,
column: 4,
name: 'foo',
});
const content = sourceContentFor(tracer, traced.source);
assert.strictEqual(content, 'content for input.js');
const generated = generatedPositionFor(tracer, {
source: 'input.js',
line: 42,
column: 4,
});
assert.deepEqual(generated, {
line: 1,
column: 5,
});
const ignored = isIgnored(tracer, 'input.js');
assert.equal(ignored, false);
```
We also provide a lower level API to get the actual segment that matches our line and column. Unlike
`originalPositionFor`, `traceSegment` uses a 0-base for `line`:
```typescript
import { traceSegment } from '@jridgewell/trace-mapping';
// line is 0-base.
const traced = traceSegment(tracer, /* line */ 0, /* column */ 5);
// Segments are [outputColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex]
// Again, line is 0-base and so is sourceLine
assert.deepEqual(traced, [5, 0, 41, 4, 0]);
```
### SectionedSourceMaps
The sourcemap spec defines a special `sections` field that's designed to handle concatenation of
output code with associated sourcemaps. This type of sourcemap is rarely used (no major build tool
produces it), but if you are hand coding a concatenation you may need it. We provide an `AnyMap`
helper that can receive either a regular sourcemap or a `SectionedSourceMap` and returns a
`TraceMap` instance:
```typescript
import { AnyMap } from '@jridgewell/trace-mapping';
const fooOutput = 'foo';
const barOutput = 'bar';
const output = [fooOutput, barOutput].join('\n');
const sectioned = new AnyMap({
version: 3,
sections: [
{
// 0-base line and column
offset: { line: 0, column: 0 },
// fooOutput's sourcemap
map: {
version: 3,
sources: ['foo.js'],
names: ['foo'],
mappings: 'AAAAA',
},
},
{
// barOutput's sourcemap will not affect the first line, only the second
offset: { line: 1, column: 0 },
map: {
version: 3,
sources: ['bar.js'],
names: ['bar'],
mappings: 'AAAAA',
},
},
],
});
const traced = originalPositionFor(sectioned, {
line: 2,
column: 0,
});
assert.deepEqual(traced, {
source: 'bar.js',
line: 1,
column: 0,
name: 'bar',
});
```
## Benchmarks
```
node v20.10.0
amp.js.map - 45120 segments
Memory Usage:
trace-mapping decoded 414164 bytes
trace-mapping encoded 6274352 bytes
source-map-js 10968904 bytes
source-map-0.6.1 17587160 bytes
source-map-0.8.0 8812155 bytes
Chrome dev tools 8672912 bytes
Smallest memory usage is trace-mapping decoded
Init speed:
trace-mapping: decoded JSON input x 205 ops/sec ±0.19% (88 runs sampled)
trace-mapping: encoded JSON input x 405 ops/sec ±1.47% (88 runs sampled)
trace-mapping: decoded Object input x 4,645 ops/sec ±0.15% (98 runs sampled)
trace-mapping: encoded Object input x 458 ops/sec ±1.63% (91 runs sampled)
source-map-js: encoded Object input x 75.48 ops/sec ±1.64% (67 runs sampled)
source-map-0.6.1: encoded Object input x 39.37 ops/sec ±1.44% (53 runs sampled)
Chrome dev tools: encoded Object input x 150 ops/sec ±1.76% (79 runs sampled)
Fastest is trace-mapping: decoded Object input
Trace speed (random):
trace-mapping: decoded originalPositionFor x 44,946 ops/sec ±0.16% (99 runs sampled)
trace-mapping: encoded originalPositionFor x 37,995 ops/sec ±1.81% (89 runs sampled)
source-map-js: encoded originalPositionFor x 9,230 ops/sec ±1.36% (93 runs sampled)
source-map-0.6.1: encoded originalPositionFor x 8,057 ops/sec ±0.84% (96 runs sampled)
source-map-0.8.0: encoded originalPositionFor x 28,198 ops/sec ±1.12% (91 runs sampled)
Chrome dev tools: encoded originalPositionFor x 46,276 ops/sec ±1.35% (95 runs sampled)
Fastest is Chrome dev tools: encoded originalPositionFor
Trace speed (ascending):
trace-mapping: decoded originalPositionFor x 204,406 ops/sec ±0.19% (97 runs sampled)
trace-mapping: encoded originalPositionFor x 196,695 ops/sec ±0.24% (99 runs sampled)
source-map-js: encoded originalPositionFor x 11,948 ops/sec ±0.94% (99 runs sampled)
source-map-0.6.1: encoded originalPositionFor x 10,730 ops/sec ±0.36% (100 runs sampled)
source-map-0.8.0: encoded originalPositionFor x 51,427 ops/sec ±0.21% (98 runs sampled)
Chrome dev tools: encoded originalPositionFor x 162,615 ops/sec ±0.18% (98 runs sampled)
Fastest is trace-mapping: decoded originalPositionFor
***
babel.min.js.map - 347793 segments
Memory Usage:
trace-mapping decoded 18504 bytes
trace-mapping encoded 35428008 bytes
source-map-js 51676808 bytes
source-map-0.6.1 63367136 bytes
source-map-0.8.0 43158400 bytes
Chrome dev tools 50721552 bytes
Smallest memory usage is trace-mapping decoded
Init speed:
trace-mapping: decoded JSON input x 17.82 ops/sec ±6.35% (35 runs sampled)
trace-mapping: encoded JSON input x 31.57 ops/sec ±7.50% (43 runs sampled)
trace-mapping: decoded Object input x 867 ops/sec ±0.74% (94 runs sampled)
trace-mapping: encoded Object input x 33.83 ops/sec ±7.66% (46 runs sampled)
source-map-js: encoded Object input x 6.58 ops/sec ±3.31% (20 runs sampled)
source-map-0.6.1: encoded Object input x 4.23 ops/sec ±3.43% (15 runs sampled)
Chrome dev tools: encoded Object input x 22.14 ops/sec ±3.79% (41 runs sampled)
Fastest is trace-mapping: decoded Object input
Trace speed (random):
trace-mapping: decoded originalPositionFor x 78,234 ops/sec ±1.48% (29 runs sampled)
trace-mapping: encoded originalPositionFor x 60,761 ops/sec ±1.35% (21 runs sampled)
source-map-js: encoded originalPositionFor x 51,448 ops/sec ±2.17% (89 runs sampled)
source-map-0.6.1: encoded originalPositionFor x 47,221 ops/sec ±1.99% (15 runs sampled)
source-map-0.8.0: encoded originalPositionFor x 84,002 ops/sec ±1.45% (27 runs sampled)
Chrome dev tools: encoded originalPositionFor x 106,457 ops/sec ±1.38% (37 runs sampled)
Fastest is Chrome dev tools: encoded originalPositionFor
Trace speed (ascending):
trace-mapping: decoded originalPositionFor x 930,943 ops/sec ±0.25% (99 runs sampled)
trace-mapping: encoded originalPositionFor x 843,545 ops/sec ±0.34% (97 runs sampled)
source-map-js: encoded originalPositionFor x 114,510 ops/sec ±1.37% (36 runs sampled)
source-map-0.6.1: encoded originalPositionFor x 87,412 ops/sec ±0.72% (92 runs sampled)
source-map-0.8.0: encoded originalPositionFor x 197,709 ops/sec ±0.89% (59 runs sampled)
Chrome dev tools: encoded originalPositionFor x 688,983 ops/sec ±0.33% (98 runs sampled)
Fastest is trace-mapping: decoded originalPositionFor
***
preact.js.map - 1992 segments
Memory Usage:
trace-mapping decoded 33136 bytes
trace-mapping encoded 254240 bytes
source-map-js 837488 bytes
source-map-0.6.1 961928 bytes
source-map-0.8.0 54384 bytes
Chrome dev tools 709680 bytes
Smallest memory usage is trace-mapping decoded
Init speed:
trace-mapping: decoded JSON input x 3,709 ops/sec ±0.13% (99 runs sampled)
trace-mapping: encoded JSON input x 6,447 ops/sec ±0.22% (101 runs sampled)
trace-mapping: decoded Object input x 83,062 ops/sec ±0.23% (100 runs sampled)
trace-mapping: encoded Object input x 14,980 ops/sec ±0.28% (100 runs sampled)
source-map-js: encoded Object input x 2,544 ops/sec ±0.16% (99 runs sampled)
source-map-0.6.1: encoded Object input x 1,221 ops/sec ±0.37% (97 runs sampled)
Chrome dev tools: encoded Object input x 4,241 ops/sec ±0.39% (93 runs sampled)
Fastest is trace-mapping: decoded Object input
Trace speed (random):
trace-mapping: decoded originalPositionFor x 91,028 ops/sec ±0.14% (94 runs sampled)
trace-mapping: encoded originalPositionFor x 84,348 ops/sec ±0.26% (98 runs sampled)
source-map-js: encoded originalPositionFor x 26,998 ops/sec ±0.23% (98 runs sampled)
source-map-0.6.1: encoded originalPositionFor x 18,049 ops/sec ±0.26% (100 runs sampled)
source-map-0.8.0: encoded originalPositionFor x 41,916 ops/sec ±0.28% (98 runs sampled)
Chrome dev tools: encoded originalPositionFor x 88,616 ops/sec ±0.14% (98 runs sampled)
Fastest is trace-mapping: decoded originalPositionFor
Trace speed (ascending):
trace-mapping: decoded originalPositionFor x 319,960 ops/sec ±0.16% (100 runs sampled)
trace-mapping: encoded originalPositionFor x 302,153 ops/sec ±0.18% (100 runs sampled)
source-map-js: encoded originalPositionFor x 35,574 ops/sec ±0.19% (100 runs sampled)
source-map-0.6.1: encoded originalPositionFor x 19,943 ops/sec ±0.12% (101 runs sampled)
source-map-0.8.0: encoded originalPositionFor x 54,648 ops/sec ±0.20% (99 runs sampled)
Chrome dev tools: encoded originalPositionFor x 278,319 ops/sec ±0.17% (102 runs sampled)
Fastest is trace-mapping: decoded originalPositionFor
***
react.js.map - 5726 segments
Memory Usage:
trace-mapping decoded 10872 bytes
trace-mapping encoded 681512 bytes
source-map-js 2563944 bytes
source-map-0.6.1 2150864 bytes
source-map-0.8.0 88680 bytes
Chrome dev tools 1149576 bytes
Smallest memory usage is trace-mapping decoded
Init speed:
trace-mapping: decoded JSON input x 1,887 ops/sec ±0.28% (99 runs sampled)
trace-mapping: encoded JSON input x 4,749 ops/sec ±0.48% (97 runs sampled)
trace-mapping: decoded Object input x 74,236 ops/sec ±0.11% (99 runs sampled)
trace-mapping: encoded Object input x 5,752 ops/sec ±0.38% (100 runs sampled)
source-map-js: encoded Object input x 806 ops/sec ±0.19% (97 runs sampled)
source-map-0.6.1: encoded Object input x 418 ops/sec ±0.33% (94 runs sampled)
Chrome dev tools: encoded Object input x 1,524 ops/sec ±0.57% (92 runs sampled)
Fastest is trace-mapping: decoded Object input
Trace speed (random):
trace-mapping: decoded originalPositionFor x 620,201 ops/sec ±0.33% (96 runs sampled)
trace-mapping: encoded originalPositionFor x 579,548 ops/sec ±0.35% (97 runs sampled)
source-map-js: encoded originalPositionFor x 230,983 ops/sec ±0.62% (54 runs sampled)
source-map-0.6.1: encoded originalPositionFor x 158,145 ops/sec ±0.80% (46 runs sampled)
source-map-0.8.0: encoded originalPositionFor x 343,801 ops/sec ±0.55% (96 runs sampled)
Chrome dev tools: encoded originalPositionFor x 659,649 ops/sec ±0.49% (98 runs sampled)
Fastest is Chrome dev tools: encoded originalPositionFor
Trace speed (ascending):
trace-mapping: decoded originalPositionFor x 2,368,079 ops/sec ±0.32% (98 runs sampled)
trace-mapping: encoded originalPositionFor x 2,134,039 ops/sec ±2.72% (87 runs sampled)
source-map-js: encoded originalPositionFor x 290,120 ops/sec ±2.49% (82 runs sampled)
source-map-0.6.1: encoded originalPositionFor x 187,613 ops/sec ±0.86% (49 runs sampled)
source-map-0.8.0: encoded originalPositionFor x 479,569 ops/sec ±0.65% (96 runs sampled)
Chrome dev tools: encoded originalPositionFor x 2,048,414 ops/sec ±0.24% (98 runs sampled)
Fastest is trace-mapping: decoded originalPositionFor
***
vscode.map - 2141001 segments
Memory Usage:
trace-mapping decoded 5206584 bytes
trace-mapping encoded 208370336 bytes
source-map-js 278493008 bytes
source-map-0.6.1 391564048 bytes
source-map-0.8.0 257508787 bytes
Chrome dev tools 291053000 bytes
Smallest memory usage is trace-mapping decoded
Init speed:
trace-mapping: decoded JSON input x 1.63 ops/sec ±33.88% (9 runs sampled)
trace-mapping: encoded JSON input x 3.29 ops/sec ±36.13% (13 runs sampled)
trace-mapping: decoded Object input x 103 ops/sec ±0.93% (77 runs sampled)
trace-mapping: encoded Object input x 5.42 ops/sec ±28.54% (19 runs sampled)
source-map-js: encoded Object input x 1.07 ops/sec ±13.84% (7 runs sampled)
source-map-0.6.1: encoded Object input x 0.60 ops/sec ±2.43% (6 runs sampled)
Chrome dev tools: encoded Object input x 2.61 ops/sec ±22.00% (11 runs sampled)
Fastest is trace-mapping: decoded Object input
Trace speed (random):
trace-mapping: decoded originalPositionFor x 257,019 ops/sec ±0.97% (93 runs sampled)
trace-mapping: encoded originalPositionFor x 179,163 ops/sec ±0.83% (92 runs sampled)
source-map-js: encoded originalPositionFor x 73,337 ops/sec ±1.35% (87 runs sampled)
source-map-0.6.1: encoded originalPositionFor x 38,797 ops/sec ±1.66% (88 runs sampled)
source-map-0.8.0: encoded originalPositionFor x 107,758 ops/sec ±1.94% (45 runs sampled)
Chrome dev tools: encoded originalPositionFor x 188,550 ops/sec ±1.85% (79 runs sampled)
Fastest is trace-mapping: decoded originalPositionFor
Trace speed (ascending):
trace-mapping: decoded originalPositionFor x 447,621 ops/sec ±3.64% (94 runs sampled)
trace-mapping: encoded originalPositionFor x 323,698 ops/sec ±5.20% (88 runs sampled)
source-map-js: encoded originalPositionFor x 78,387 ops/sec ±1.69% (89 runs sampled)
source-map-0.6.1: encoded originalPositionFor x 41,016 ops/sec ±3.01% (25 runs sampled)
source-map-0.8.0: encoded originalPositionFor x 124,204 ops/sec ±0.90% (92 runs sampled)
Chrome dev tools: encoded originalPositionFor x 230,087 ops/sec ±2.61% (93 runs sampled)
Fastest is trace-mapping: decoded originalPositionFor
```
[source-map]: https://www.npmjs.com/package/source-map

View File

@ -1,67 +0,0 @@
{
"name": "@jridgewell/trace-mapping",
"version": "0.3.31",
"description": "Trace the original position through a source map",
"keywords": [
"source",
"map"
],
"main": "dist/trace-mapping.umd.js",
"module": "dist/trace-mapping.mjs",
"types": "types/trace-mapping.d.cts",
"files": [
"dist",
"src",
"types"
],
"exports": {
".": [
{
"import": {
"types": "./types/trace-mapping.d.mts",
"default": "./dist/trace-mapping.mjs"
},
"default": {
"types": "./types/trace-mapping.d.cts",
"default": "./dist/trace-mapping.umd.js"
}
},
"./dist/trace-mapping.umd.js"
],
"./package.json": "./package.json"
},
"scripts": {
"benchmark": "run-s build:code benchmark:*",
"benchmark:install": "cd benchmark && npm install",
"benchmark:only": "node --expose-gc benchmark/index.mjs",
"build": "run-s -n build:code build:types",
"build:code": "node ../../esbuild.mjs trace-mapping.ts",
"build:types": "run-s build:types:force build:types:emit build:types:mts",
"build:types:force": "rimraf tsconfig.build.tsbuildinfo",
"build:types:emit": "tsc --project tsconfig.build.json",
"build:types:mts": "node ../../mts-types.mjs",
"clean": "run-s -n clean:code clean:types",
"clean:code": "tsc --build --clean tsconfig.build.json",
"clean:types": "rimraf dist types",
"test": "run-s -n test:types test:only test:format",
"test:format": "prettier --check '{src,test}/**/*.ts'",
"test:only": "mocha",
"test:types": "eslint '{src,test}/**/*.ts'",
"lint": "run-s -n lint:types lint:format",
"lint:format": "npm run test:format -- --write",
"lint:types": "npm run test:types -- --fix",
"prepublishOnly": "npm run-s -n build test"
},
"homepage": "https://github.com/jridgewell/sourcemaps/tree/main/packages/trace-mapping",
"repository": {
"type": "git",
"url": "git+https://github.com/jridgewell/sourcemaps.git",
"directory": "packages/trace-mapping"
},
"author": "Justin Ridgewell <justin@ridgewell.name>",
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
}

View File

@ -1,115 +0,0 @@
import type { SourceMapSegment, ReverseSegment } from './sourcemap-segment';
import { COLUMN } from './sourcemap-segment';
export type MemoState = {
lastKey: number;
lastNeedle: number;
lastIndex: number;
};
export let found = false;
/**
* A binary search implementation that returns the index if a match is found.
* If no match is found, then the left-index (the index associated with the item that comes just
* before the desired index) is returned. To maintain proper sort order, a splice would happen at
* the next index:
*
* ```js
* const array = [1, 3];
* const needle = 2;
* const index = binarySearch(array, needle, (item, needle) => item - needle);
*
* assert.equal(index, 0);
* array.splice(index + 1, 0, needle);
* assert.deepEqual(array, [1, 2, 3]);
* ```
*/
export function binarySearch(
haystack: SourceMapSegment[] | ReverseSegment[],
needle: number,
low: number,
high: number,
): number {
while (low <= high) {
const mid = low + ((high - low) >> 1);
const cmp = haystack[mid][COLUMN] - needle;
if (cmp === 0) {
found = true;
return mid;
}
if (cmp < 0) {
low = mid + 1;
} else {
high = mid - 1;
}
}
found = false;
return low - 1;
}
export function upperBound(
haystack: SourceMapSegment[] | ReverseSegment[],
needle: number,
index: number,
): number {
for (let i = index + 1; i < haystack.length; index = i++) {
if (haystack[i][COLUMN] !== needle) break;
}
return index;
}
export function lowerBound(
haystack: SourceMapSegment[] | ReverseSegment[],
needle: number,
index: number,
): number {
for (let i = index - 1; i >= 0; index = i--) {
if (haystack[i][COLUMN] !== needle) break;
}
return index;
}
export function memoizedState(): MemoState {
return {
lastKey: -1,
lastNeedle: -1,
lastIndex: -1,
};
}
/**
* This overly complicated beast is just to record the last tested line/column and the resulting
* index, allowing us to skip a few tests if mappings are monotonically increasing.
*/
export function memoizedBinarySearch(
haystack: SourceMapSegment[] | ReverseSegment[],
needle: number,
state: MemoState,
key: number,
): number {
const { lastKey, lastNeedle, lastIndex } = state;
let low = 0;
let high = haystack.length - 1;
if (key === lastKey) {
if (needle === lastNeedle) {
found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle;
return lastIndex;
}
if (needle >= lastNeedle) {
// lastIndex may be -1 if the previous needle was not found.
low = lastIndex === -1 ? 0 : lastIndex;
} else {
high = lastIndex;
}
}
state.lastKey = key;
state.lastNeedle = needle;
return (state.lastIndex = binarySearch(haystack, needle, low, high));
}

View File

@ -1,41 +0,0 @@
import { COLUMN, SOURCES_INDEX, SOURCE_LINE, SOURCE_COLUMN } from './sourcemap-segment';
import { sortComparator } from './sort';
import type { ReverseSegment, SourceMapSegment } from './sourcemap-segment';
export type Source = ReverseSegment[][];
// Rebuilds the original source files, with mappings that are ordered by source line/column instead
// of generated line/column.
export default function buildBySources(
decoded: readonly SourceMapSegment[][],
memos: unknown[],
): Source[] {
const sources: Source[] = memos.map(() => []);
for (let i = 0; i < decoded.length; i++) {
const line = decoded[i];
for (let j = 0; j < line.length; j++) {
const seg = line[j];
if (seg.length === 1) continue;
const sourceIndex = seg[SOURCES_INDEX];
const sourceLine = seg[SOURCE_LINE];
const sourceColumn = seg[SOURCE_COLUMN];
const source = sources[sourceIndex];
const segs = (source[sourceLine] ||= []);
segs.push([sourceColumn, i, seg[COLUMN]]);
}
}
for (let i = 0; i < sources.length; i++) {
const source = sources[i];
for (let j = 0; j < source.length; j++) {
const line = source[j];
if (line) line.sort(sortComparator);
}
}
return sources;
}

View File

@ -1,192 +0,0 @@
import { TraceMap, presortedDecodedMap, decodedMappings } from './trace-mapping';
import {
COLUMN,
SOURCES_INDEX,
SOURCE_LINE,
SOURCE_COLUMN,
NAMES_INDEX,
} from './sourcemap-segment';
import { parse } from './types';
import type {
DecodedSourceMap,
DecodedSourceMapXInput,
EncodedSourceMapXInput,
SectionedSourceMapXInput,
SectionedSourceMapInput,
SectionXInput,
Ro,
} from './types';
import type { SourceMapSegment } from './sourcemap-segment';
type FlattenMap = {
new (map: Ro<SectionedSourceMapInput>, mapUrl?: string | null): TraceMap;
(map: Ro<SectionedSourceMapInput>, mapUrl?: string | null): TraceMap;
};
export const FlattenMap: FlattenMap = function (map, mapUrl) {
const parsed = parse(map as SectionedSourceMapInput);
if (!('sections' in parsed)) {
return new TraceMap(parsed as DecodedSourceMapXInput | EncodedSourceMapXInput, mapUrl);
}
const mappings: SourceMapSegment[][] = [];
const sources: string[] = [];
const sourcesContent: (string | null)[] = [];
const names: string[] = [];
const ignoreList: number[] = [];
recurse(
parsed,
mapUrl,
mappings,
sources,
sourcesContent,
names,
ignoreList,
0,
0,
Infinity,
Infinity,
);
const joined: DecodedSourceMap = {
version: 3,
file: parsed.file,
names,
sources,
sourcesContent,
mappings,
ignoreList,
};
return presortedDecodedMap(joined);
} as FlattenMap;
function recurse(
input: SectionedSourceMapXInput,
mapUrl: string | null | undefined,
mappings: SourceMapSegment[][],
sources: string[],
sourcesContent: (string | null)[],
names: string[],
ignoreList: number[],
lineOffset: number,
columnOffset: number,
stopLine: number,
stopColumn: number,
) {
const { sections } = input;
for (let i = 0; i < sections.length; i++) {
const { map, offset } = sections[i];
let sl = stopLine;
let sc = stopColumn;
if (i + 1 < sections.length) {
const nextOffset = sections[i + 1].offset;
sl = Math.min(stopLine, lineOffset + nextOffset.line);
if (sl === stopLine) {
sc = Math.min(stopColumn, columnOffset + nextOffset.column);
} else if (sl < stopLine) {
sc = columnOffset + nextOffset.column;
}
}
addSection(
map,
mapUrl,
mappings,
sources,
sourcesContent,
names,
ignoreList,
lineOffset + offset.line,
columnOffset + offset.column,
sl,
sc,
);
}
}
function addSection(
input: SectionXInput['map'],
mapUrl: string | null | undefined,
mappings: SourceMapSegment[][],
sources: string[],
sourcesContent: (string | null)[],
names: string[],
ignoreList: number[],
lineOffset: number,
columnOffset: number,
stopLine: number,
stopColumn: number,
) {
const parsed = parse(input);
if ('sections' in parsed) return recurse(...(arguments as unknown as Parameters<typeof recurse>));
const map = new TraceMap(parsed, mapUrl);
const sourcesOffset = sources.length;
const namesOffset = names.length;
const decoded = decodedMappings(map);
const { resolvedSources, sourcesContent: contents, ignoreList: ignores } = map;
append(sources, resolvedSources);
append(names, map.names);
if (contents) append(sourcesContent, contents);
else for (let i = 0; i < resolvedSources.length; i++) sourcesContent.push(null);
if (ignores) for (let i = 0; i < ignores.length; i++) ignoreList.push(ignores[i] + sourcesOffset);
for (let i = 0; i < decoded.length; i++) {
const lineI = lineOffset + i;
// We can only add so many lines before we step into the range that the next section's map
// controls. When we get to the last line, then we'll start checking the segments to see if
// they've crossed into the column range. But it may not have any columns that overstep, so we
// still need to check that we don't overstep lines, too.
if (lineI > stopLine) return;
// The out line may already exist in mappings (if we're continuing the line started by a
// previous section). Or, we may have jumped ahead several lines to start this section.
const out = getLine(mappings, lineI);
// On the 0th loop, the section's column offset shifts us forward. On all other lines (since the
// map can be multiple lines), it doesn't.
const cOffset = i === 0 ? columnOffset : 0;
const line = decoded[i];
for (let j = 0; j < line.length; j++) {
const seg = line[j];
const column = cOffset + seg[COLUMN];
// If this segment steps into the column range that the next section's map controls, we need
// to stop early.
if (lineI === stopLine && column >= stopColumn) return;
if (seg.length === 1) {
out.push([column]);
continue;
}
const sourcesIndex = sourcesOffset + seg[SOURCES_INDEX];
const sourceLine = seg[SOURCE_LINE];
const sourceColumn = seg[SOURCE_COLUMN];
out.push(
seg.length === 4
? [column, sourcesIndex, sourceLine, sourceColumn]
: [column, sourcesIndex, sourceLine, sourceColumn, namesOffset + seg[NAMES_INDEX]],
);
}
}
}
function append<T>(arr: T[], other: T[]) {
for (let i = 0; i < other.length; i++) arr.push(other[i]);
}
function getLine<T>(arr: T[][], index: number): T[] {
for (let i = arr.length; i <= index; i++) arr[i] = [];
return arr[index];
}

View File

@ -1,16 +0,0 @@
import resolveUri from '@jridgewell/resolve-uri';
import stripFilename from './strip-filename';
type Resolve = (source: string | null) => string;
export default function resolver(
mapUrl: string | null | undefined,
sourceRoot: string | undefined,
): Resolve {
const from = stripFilename(mapUrl);
// The sourceRoot is always treated as a directory, if it's not empty.
// https://github.com/mozilla/source-map/blob/8cb3ee57/lib/util.js#L327
// https://github.com/chromium/chromium/blob/da4adbb3/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js#L400-L401
const prefix = sourceRoot ? sourceRoot + '/' : '';
return (source) => resolveUri(prefix + (source || ''), from);
}

View File

@ -1,45 +0,0 @@
import { COLUMN } from './sourcemap-segment';
import type { ReverseSegment, SourceMapSegment } from './sourcemap-segment';
export default function maybeSort(
mappings: SourceMapSegment[][],
owned: boolean,
): SourceMapSegment[][] {
const unsortedIndex = nextUnsortedSegmentLine(mappings, 0);
if (unsortedIndex === mappings.length) return mappings;
// If we own the array (meaning we parsed it from JSON), then we're free to directly mutate it. If
// not, we do not want to modify the consumer's input array.
if (!owned) mappings = mappings.slice();
for (let i = unsortedIndex; i < mappings.length; i = nextUnsortedSegmentLine(mappings, i + 1)) {
mappings[i] = sortSegments(mappings[i], owned);
}
return mappings;
}
function nextUnsortedSegmentLine(mappings: SourceMapSegment[][], start: number): number {
for (let i = start; i < mappings.length; i++) {
if (!isSorted(mappings[i])) return i;
}
return mappings.length;
}
function isSorted(line: SourceMapSegment[]): boolean {
for (let j = 1; j < line.length; j++) {
if (line[j][COLUMN] < line[j - 1][COLUMN]) {
return false;
}
}
return true;
}
function sortSegments(line: SourceMapSegment[], owned: boolean): SourceMapSegment[] {
if (!owned) line = line.slice();
return line.sort(sortComparator);
}
export function sortComparator<T extends SourceMapSegment | ReverseSegment>(a: T, b: T): number {
return a[COLUMN] - b[COLUMN];
}

View File

@ -1,23 +0,0 @@
type GeneratedColumn = number;
type SourcesIndex = number;
type SourceLine = number;
type SourceColumn = number;
type NamesIndex = number;
type GeneratedLine = number;
export type SourceMapSegment =
| [GeneratedColumn]
| [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn]
| [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex];
export type ReverseSegment = [SourceColumn, GeneratedLine, GeneratedColumn];
export const COLUMN = 0;
export const SOURCES_INDEX = 1;
export const SOURCE_LINE = 2;
export const SOURCE_COLUMN = 3;
export const NAMES_INDEX = 4;
export const REV_GENERATED_LINE = 1;
export const REV_GENERATED_COLUMN = 2;

View File

@ -1,8 +0,0 @@
/**
* Removes everything after the last "/", but leaves the slash.
*/
export default function stripFilename(path: string | undefined | null): string {
if (!path) return '';
const index = path.lastIndexOf('/');
return path.slice(0, index + 1);
}

Some files were not shown because too many files have changed in this diff Show More