{"id":41709075,"url":"https://github.com/pkeffect/pwa-framework","last_synced_at":"2026-01-24T21:40:04.580Z","repository":{"id":332017201,"uuid":"1132466878","full_name":"pkeffect/pwa-framework","owner":"pkeffect","description":"a zero-dependency Python script that scaffolds complete, production-ready Progressive Web App frameworks optimized for game development. Generate 24 files across 11 directories in ~150ms with enterprise-grade features built in.","archived":false,"fork":false,"pushed_at":"2026-01-12T04:59:38.000Z","size":260,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-12T07:37:57.149Z","etag":null,"topics":["css","html","js","python","webgl"],"latest_commit_sha":null,"homepage":"https://internode.info/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pkeffect.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":"AUDIT.md","citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":"SUPPORT.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-12T01:59:51.000Z","updated_at":"2026-01-12T04:51:58.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pkeffect/pwa-framework","commit_stats":null,"previous_names":["pkeffect/pwa-framework"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/pkeffect/pwa-framework","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pkeffect%2Fpwa-framework","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pkeffect%2Fpwa-framework/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pkeffect%2Fpwa-framework/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pkeffect%2Fpwa-framework/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pkeffect","download_url":"https://codeload.github.com/pkeffect/pwa-framework/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pkeffect%2Fpwa-framework/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28737558,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T21:19:41.845Z","status":"ssl_error","status_checked_at":"2026-01-24T21:13:38.675Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["css","html","js","python","webgl"],"created_at":"2026-01-24T21:40:03.569Z","updated_at":"2026-01-24T21:40:04.504Z","avatar_url":"https://github.com/pkeffect.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PWA Game Framework Generator\n\n\u003cdiv align=\"center\"\u003e\n\n![Version](https://img.shields.io/badge/version-2.0.1-blue.svg)\n![Python](https://img.shields.io/badge/python-3.10--3.12-green.svg)\n![License](https://img.shields.io/badge/license-MIT-orange.svg)\n![Build Time](https://img.shields.io/badge/build_time-~150ms-brightgreen.svg)\n![Dependencies](https://img.shields.io/badge/dependencies-zero-success.svg)\n![Tests](https://github.com/pkeffect/pwa-framework/actions/workflows/validate.yml/badge.svg)\n\n**Generate production-ready PWA game frameworks in milliseconds.**\n\n[Features](#-features) • [Quick Start](#-quick-start) • [Installation](#-installation) • [Documentation](#-documentation) • [Examples](#-examples)\n\n\u003c/div\u003e\n\n---\n\n## 🎯 Overview\n\n**PWA Game Framework Generator** is a zero-dependency Python script that scaffolds complete, production-ready Progressive Web App frameworks optimized for game development. Generate 24 files across 11 directories in ~150ms with enterprise-grade features built in.\n\n### What You Get\n\n- ✨ **Zero Build Step** - Deploy instantly, no compilation required\n- 🚀 **~150ms Generation** - Complete framework in milliseconds\n- 📦 **50KB Footprint** - Entire output smaller than most libraries\n- ♿ **WCAG 2.1 AA** - Accessibility built-in from day one\n- 🔐 **Security Hardened** - CSP, SRI, input validation, error recovery\n- 🎨 **High DPI Ready** - Retina display support out of the box\n- 📱 **PWA Native** - Installable, offline-capable, app-like\n- 🎮 **Game-Focused** - Optimized for game jams, prototypes, education\n\n---\n\n## ✨ Features\n\n### Framework Output\n\n| Feature | Description |\n|---------|-------------|\n| **ES6 Modules** | Native browser modules, no bundler required |\n| **Service Worker** | Offline-first with cache versioning |\n| **Asset Pipeline** | Chunked loading with retry logic (2 retries, exponential backoff) |\n| **High DPI Canvas** | Auto-scaling for 4K/Retina displays |\n| **Scene System** | State machine for menu/game/pause screens |\n| **Error Handling** | 3-layer protection (sync/async/resource) |\n| **Audio Manager** | Context unlocking for mobile browsers |\n| **Accessibility** | Keyboard nav, ARIA labels, focus trapping |\n| **Security** | CSP headers (no 'unsafe-inline'), SRI hashes, input sanitization |\n| **Dark Mode** | Auto-adapts to system preference (light/dark) |\n| **Cache Management** | 50MB size limit with automatic cleanup |\n| **Asset Validation** | Image dimension checks (1x1 min, 8192x8192 max) |\n| **Browser Compat** | Vendor prefixes for Safari 11+ support |\n| **Battery Optimization** | Visibility API integration |\n\n### Generator Features\n\n| Feature | Description |\n|---------|-------------|\n| **Input Validation** | Sanitization-first approach (fixes vs rejects) |\n| **Error Recovery** | Comprehensive exception handling |\n| **CLI Interface** | Interactive \u0026 non-interactive modes, dry-run support |\n| **Zero Dependencies** | Pure Python stdlib (argparse, pathlib, json, re) |\n| **Cross-Platform** | Windows, macOS, Linux compatible |\n| **Test Coverage** | 33 unit tests, 81% code coverage (pytest) |\n| **Documentation** | 788-line README in every generated project |\n\n---\n\n## 🚀 Quick Start\n\n### Prerequisites\n\n- Python 3.10 - 3.12 (uses `pathlib`, f-strings, match-case)\n- Modern web browser for testing generated output\n- HTTP server for local development (Python's built-in works)\n\n### Installation\n\n```bash\n# Clone or download pwa_create.py\ncurl -O https://raw.githubusercontent.com/pkeffect/pwa-framework-generator/main/pwa_create.py\n\n# Or just download the single file - no installation needed!\n```\n\n### Generate Your First Framework\n\n```bash\n# Interactive mode\npython pwa_create.py\n\n# Non-interactive mode\npython pwa_create.py my-awesome-game\n\n# With spaces (auto-sanitized)\npython pwa_create.py \"Space Shooter 2024\"\n```\n\n### Run the Generated Project\n\n```bash\ncd my-awesome-game\npython -m http.server 8000\n\n# Open browser to http://localhost:8000\n```\n\n---\n\n## 📂 Generated Project Structure\n\n```\nmy-awesome-game/\n├── index.html              # 119 lines - Entry point with CSP, SRI, ARIA\n├── manifest.json           # 8 lines - PWA configuration\n├── service-worker.js       # 60 lines - Cache versioning, fetch strategy\n├── README.md               # 788 lines - Comprehensive documentation\n├── .gitignore              # 6 lines - Standard exclusions\n│\n├── assets/                 # Media directory (empty scaffolding)\n│   ├── icons/             # PWA icons (192x192, 512x512)\n│   ├── audio/             # Sound effects, music\n│   ├── textures/          # Sprites, backgrounds\n│   ├── models/            # 3D models (optional)\n│   └── shaders/           # WebGL shaders (optional)\n│\n├── css/\n│   ├── main.css           # 89 lines - Reset, layout, canvas\n│   └── ui.css             # 147 lines - Modals, sidebar, glassmorphism\n│\n└── js/\n    ├── main.js            # 36 lines - Bootstrap \u0026 initialization\n    ├── core/              # Engine layer (156 lines total)\n    ├── scenes/            # State machines (52 lines total)\n    ├── state/             # Data persistence (45 lines total)\n    ├── ui/                # DOM interaction (120 lines total)\n    └── utils/             # Helpers (43 lines total)\n```\n\n**Total Output:** 24 files, 1,460 lines of code, ~50KB uncompressed\n\n---\n\n## 🛠️ Usage\n\n### Command-Line Interface\n\n```bash\n# Show help\npython pwa_create.py --help\n\n# Show version\npython pwa_create.py --version\n\n# Dry-run mode (preview without creating files)\npython pwa_create.py my-game --dry-run\n\n# Interactive mode (prompts for name)\npython pwa_create.py\n\n# Direct mode\npython pwa_create.py my-game\n\n# With special characters (auto-sanitized)\npython pwa_create.py \"My Game!\"\n# → Creates: my-game/\n```\n\n### Project Name Rules\n\n| Rule | Description | Example |\n|------|-------------|---------|\n| **Length** | 1-50 characters | ✅ `my-game` ✅ `super-long-game-title-2024` |\n| **First Char** | Must be alphanumeric | ✅ `g1` ❌ `-game` |\n| **Allowed Chars** | Letters, numbers, hyphens, underscores | ✅ `my_game-2024` ❌ `my@game` |\n| **Sanitization** | Auto-lowercase, spaces→hyphens | `My Game` → `my-game` |\n\n### Python API\n\n```python\nfrom pathlib import Path\nimport sys\n\n# Add script directory to path\nsys.path.insert(0, str(Path(__file__).parent))\n\nfrom pwa_create import create_framework, validate_project_name\n\n# Validate name\ntry:\n    clean_name = validate_project_name(\"My Game 2024\")\n    print(f\"Sanitized: {clean_name}\")  # \"my-game-2024\"\nexcept ValueError as e:\n    print(f\"Invalid: {e}\")\n\n# Generate framework\nsuccess = create_framework(\"my-game\")\nif success:\n    print(\"✅ Framework created!\")\nelse:\n    print(\"❌ Generation failed\")\n```\n\n---\n\n## 🧪 Testing \u0026 Development\n\n### Running Tests\n\nThe generator includes a comprehensive test suite with 81% code coverage:\n\n```bash\n# Install test dependencies\npip install -r requirements-dev.txt\n\n# Run all tests\npython -m pytest tests/test_pwa_create.py -v\n\n# Run with coverage report\npython -m pytest tests/test_pwa_create.py --cov=pwa_create --cov-report=html\n\n# Open coverage report\nopen htmlcov/index.html  # macOS\nstart htmlcov/index.html  # Windows\n```\n\n### Test Suite Coverage\n\n- **Input Validation** (10 tests) - Path traversal, script injection, sanitization\n- **Template Generation** (10 tests) - CSP, dark mode, cache limits, version metadata\n- **Framework Creation** (6 tests) - File generation, directory structure, dry-run mode\n- **Edge Cases** (4 tests) - Unicode, numeric names, length limits\n- **Constants** (3 tests) - Version format, configuration bounds\n\n### CI/CD\n\nAll commits are validated via GitHub Actions:\n- ✅ Cross-platform testing (Ubuntu, Windows, macOS)\n- ✅ Python 3.10, 3.11, 3.12 compatibility\n- ✅ Unit test suite execution\n- ✅ Generated project validation\n- ✅ Security checks (CSP, eval(), imports)\n- ✅ Feature verification (dark mode, cache limits, metadata)\n\n---\n\n## 📚 Documentation\n\n### For Developers (Using Generated Frameworks)\n\nEach generated project includes a comprehensive 788-line `README.md` with:\n\n- 🏗️ Architecture breakdown\n- 🎮 Quick start tutorial\n- 📖 API reference for all modules\n- 🐛 Troubleshooting guide\n- 🚀 Deployment instructions (Netlify, Vercel, GitHub Pages)\n- 🔒 Security documentation\n- ♿ Accessibility guidelines\n\n### For LLMs \u0026 Tool Developers\n\nSee [`DEVELOPER.md`](./DEVELOPER.md) for:\n\n- Complete design pattern explanations\n- Extension point documentation\n- Common assistance scenarios\n- Performance best practices\n- Architecture deep dives\n\n### For Auditors \u0026 Reviewers\n\nSee [`AUDIT.md`](./AUDIT.md) for:\n\n- Feature comparison vs competitors\n- Security posture analysis\n- Performance benchmarks\n- Code quality metrics\n- Grading \u0026 recommendations\n\n---\n\n## 🎮 Examples\n\n### Minimal Game Implementation\n\nAfter generating a framework, edit `js/scenes/GameScene.js`:\n\n```javascript\nimport { Renderer } from '../core/Renderer.js';\nimport { AssetLoader } from '../core/AssetLoader.js';\n\nexport class GameScene {\n    enter() {\n        this.canvas = Renderer.canvas;\n        this.ctx = this.canvas.getContext('2d');\n        \n        this.player = {\n            x: this.canvas.width / 2,\n            y: this.canvas.height / 2,\n            speed: 300\n        };\n        \n        this.keys = {};\n        window.addEventListener('keydown', e =\u003e this.keys[e.key] = true);\n        window.addEventListener('keyup', e =\u003e this.keys[e.key] = false);\n    }\n    \n    update(dt) {\n        if (this.keys['ArrowLeft']) this.player.x -= this.player.speed * dt;\n        if (this.keys['ArrowRight']) this.player.x += this.player.speed * dt;\n        if (this.keys['ArrowUp']) this.player.y -= this.player.speed * dt;\n        if (this.keys['ArrowDown']) this.player.y += this.player.speed * dt;\n    }\n    \n    render() {\n        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n        this.ctx.fillStyle = '#00ff00';\n        this.ctx.fillRect(this.player.x - 10, this.player.y - 10, 20, 20);\n    }\n    \n    exit() {\n        // Cleanup\n    }\n}\n```\n\nRun with `python -m http.server 8000` and open `http://localhost:8000`.\n\n### With Assets\n\nEdit `js/main.js`:\n\n```javascript\nconst MANIFEST = [\n    { type: 'image', src: 'assets/textures/player.png', key: 'player' },\n    { type: 'audio', src: 'assets/audio/jump.mp3', key: 'jump' }\n];\n```\n\nUse in GameScene:\n\n```javascript\nrender() {\n    const playerImg = AssetLoader.get('player');\n    if (playerImg) {\n        this.ctx.drawImage(playerImg, this.player.x, this.player.y);\n    }\n}\n```\n\n---\n\n## 🔍 Comparison\n\n### vs. Create React App\n\n| Feature | PWA Generator | Create React App |\n|---------|---------------|------------------|\n| **Setup Time** | 0.15s | 45-90s |\n| **Footprint** | 50KB | ~300MB |\n| **Dependencies** | 0 | 1,500+ packages |\n| **Build Step** | None | Required (Webpack) |\n| **Boot Time** | 28ms | 3-5s |\n| **HMR** | No | Yes |\n| **Framework** | Vanilla JS | React |\n| **Best For** | Games, prototypes | Web apps |\n\n### vs. Vite\n\n| Feature | PWA Generator | Vite |\n|---------|---------------|------|\n| **Setup Time** | 0.15s | 15-30s |\n| **Footprint** | 50KB | ~30MB |\n| **Dependencies** | 0 | 200+ packages |\n| **Build Step** | None | Required (Rollup) |\n| **Dev Server** | Any HTTP | Built-in with HMR |\n| **Production Build** | Copy files | Bundle + optimize |\n| **Best For** | Zero-config games | Modern web apps |\n\n### vs. Phaser\n\n| Feature | PWA Generator | Phaser 3 |\n|---------|---------------|----------|\n| **Setup** | Single script | npm install |\n| **Bundle Size** | 50KB framework | ~700KB library |\n| **Learning Curve** | Low (vanilla JS) | Medium (Phaser API) |\n| **Physics** | DIY | Built-in (Arcade, Matter) |\n| **Rendering** | Canvas 2D | Canvas + WebGL |\n| **Scene System** | Simple state machine | Full lifecycle engine |\n| **Best For** | Education, jams | Production games |\n\n---\n\n## 🏆 Use Cases\n\n### ✅ Perfect For\n\n- **Game Jams** - Generate, code, deploy in hours\n- **Prototyping** - Test ideas without setup overhead\n- **Education** - Learn web development without tooling complexity\n- **Portfolio Projects** - Showcase games without framework lock-in\n- **Offline Tools** - PWA features for offline-first apps\n- **Minimal MVPs** - Ship fast with zero dependencies\n\n### ❌ Not Ideal For\n\n- **Large Teams** - TypeScript + tooling better for collaboration\n- **Complex Games** - Use Phaser, PixiJS, or Unity WebGL\n- **Hot Module Replacement** - Use Vite or Webpack dev server\n- **React/Vue Projects** - Use framework-specific generators\n\n---\n\n## 🔒 Security\n\n### Generator Script\n\n- ✅ Input validation with regex patterns\n- ✅ Path traversal prevention (pathlib)\n- ✅ No code execution from user input\n- ✅ Exception handling for all file operations\n\n### Generated Output\n\n- ✅ Content Security Policy (CSP) headers\n- ✅ Subresource Integrity (SRI) for CDN assets\n- ✅ Input sanitization patterns\n- ✅ Service worker cache versioning\n- ✅ No eval() or unsafe code execution\n\n---\n\n## ♿ Accessibility\n\nAll generated frameworks are **WCAG 2.1 AA compliant**:\n\n- ✅ Keyboard navigation (`Tab`, `Shift+Tab`, `ESC`)\n- ✅ ARIA attributes on all interactive elements\n- ✅ Focus trapping in modals\n- ✅ Screen reader support\n- ✅ Semantic HTML structure\n\n---\n\n## 🧪 Testing Generated Frameworks\n\n```bash\n# Generate test project\npython pwa_create.py test-game\n\n# Start local server\ncd test-game\npython -m http.server 8000\n\n# Open browser\n# Visit: http://localhost:8000\n\n# Test PWA features (Chrome DevTools)\n# 1. Application tab → Service Workers (should be registered)\n# 2. Application tab → Manifest (should show name, icons)\n# 3. Lighthouse audit (should score 90+ on PWA)\n\n# Test offline mode\n# 1. Load page once\n# 2. DevTools → Network → Offline checkbox\n# 3. Refresh page (should load from cache)\n```\n\n---\n\n## 📈 Performance\n\n### Generation Benchmarks\n\n| Metric | Value |\n|--------|-------|\n| **Cold Start** | 147ms |\n| **Warm Start** | 152ms |\n| **Files Created** | 24 |\n| **Directories Created** | 11 |\n| **Lines of Code** | 1,460 |\n| **Memory Usage** | \u003c5MB |\n\n*Tested on: Windows 11, Intel i7-10700K, Python 3.11*\n\n### Generated Framework Benchmarks\n\n| Metric | Value |\n|--------|-------|\n| **Boot Time** | 28ms |\n| **First Paint** | 120ms |\n| **Time to Interactive** | 180ms |\n| **Lighthouse PWA Score** | 92/100 |\n| **Lighthouse Performance** | 98/100 |\n\n*Tested on: Chrome 120, throttled 4x CPU, Fast 3G network*\n\n---\n\n## 🤝 Contributing\n\nContributions welcome! This is a single-file generator, so changes are straightforward.\n\n### Development Setup\n\n```bash\n# Clone repository\ngit clone https://github.com/pkeffect/pwa-framework-generator.git\ncd pwa-framework-generator\n\n# No installation needed - just edit pwa_create.py\n\n# Test changes\npython pwa_create.py test-output\ncd test-output\npython -m http.server 8000\n```\n\n### Code Quality\n\n```bash\n# Lint with flake8\npip install flake8\nflake8 pwa_create.py --max-line-length=100\n\n# Type check with mypy\npip install mypy\nmypy pwa_create.py\n\n# Format with black\npip install black\nblack pwa_create.py\n```\n\n### Adding Features\n\n1. **New File Templates** - Add static method to `Templates` class\n2. **Validation Rules** - Edit `validate_project_name()` function\n3. **File Creation** - Add write operation in `create_framework()`\n4. **Documentation** - Update generated README template\n\n---\n\n## 📝 License\n\n**MIT License**\n\nCopyright (c) 2024-2026 pkeffect\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n---\n\n## 🙏 Acknowledgments\n\n- **Inspiration:** Frustrated by complex build tools for simple game projects\n- **Philosophy:** [Vanilla JavaScript](http://vanilla-js.com/) movement\n- **Architecture:** Progressive Web App best practices from [web.dev](https://web.dev)\n- **Accessibility:** WCAG 2.1 guidelines from [W3C](https://www.w3.org/WAI/WCAG21/quickref/)\n\n---\n\n## 📞 Support\n\n- 🐛 **Bug Reports:** [GitHub Issues](https://github.com/pkeffect/pwa-framework-generator/issues)\n- 💡 **Feature Requests:** [GitHub Discussions](https://github.com/pkeffect/pwa-framework-generator/discussions)\n- 📧 **Email:** pkeffect@gmail.com\n- 🌐 **Website:** https://internode.info/\n\n---\n\n## 🗺️ Roadmap\n\n### v2.1.0 (Planned)\n\n- [ ] TypeScript template option\n- [ ] WebGL renderer template\n- [ ] Touch input handler\n- [ ] Multiple theme presets (dark, light, cyberpunk)\n- [ ] Asset optimizer (image compression, audio conversion)\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n**Built with ❤️ for developers who value simplicity over complexity.**\n\n[⬆ Back to Top](#pwa-game-framework-generator)\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpkeffect%2Fpwa-framework","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpkeffect%2Fpwa-framework","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpkeffect%2Fpwa-framework/lists"}