UNPKG

awake-lock

Version:

A comprehensive wake lock library for preventing device sleep with intelligent fallback strategies and exceptional performance

412 lines (312 loc) 10.6 kB
# AwakeLock 🔋 A comprehensive, framework-agnostic TypeScript library for preventing device sleep with intelligent fallback strategies, battery optimization, and performance monitoring. [![npm version](https://img.shields.io/npm/v/awake-lock.svg)](https://www.npmjs.com/package/awake-lock) [![Bundle size](https://img.shields.io/bundlephobia/minzip/awake-lock.svg)](https://bundlephobia.com/result?p=awake-lock) [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/) [![Browser support](https://img.shields.io/badge/Browser-95%2B%25-green.svg)](#browser-support) [![Tests](https://img.shields.io/badge/Tests-25%2F25%20Passing-green.svg)](#testing) [![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) ## Features - 🔋 **Modern Screen Wake Lock API** with intelligent fallback strategies - 🌐 **Universal Support** - Works with React, Vue, Angular, and Vanilla JS - 🛡️ **Passive Mode** - Fail silently when user permission prompts would be disruptive - 🔧 **Pluggable Strategy System** - Custom fallback implementations - 📊 **Battery Optimization** - Automatic release on low battery - 📈 **Performance Monitoring** - Track resource usage and battery impact - 🎯 **TypeScript First** - Complete type safety with strict mode - 📱 **Mobile Optimized** - Special handling for iOS Safari and mobile browsers - 🎨 **Framework Integrations** - Hooks, composables, and services included - 🏗️ **SSR Safe** - Server-side rendering compatible ## Installation ```bash # Using npm npm install awake-lock # Using pnpm (recommended) pnpm add awake-lock # Using yarn yarn add awake-lock ``` ## Package Structure ## Quick Start ### Vanilla JavaScript/TypeScript ```typescript import { WakeLock } from 'awake-lock'; const wakeLock = new WakeLock(); // Request wake lock const sentinel = await wakeLock.request('screen'); // Release wake lock await wakeLock.release(); ``` ### React Hook ```tsx import { useWakeLock } from 'awake-lock'; function VideoPlayer() { const { isActive, request, release, isSupported } = useWakeLock({ onEnabled: () => console.log('Wake lock enabled'), onDisabled: () => console.log('Wake lock disabled'), }); return ( <div> {isSupported ? ( <button onClick={() => (isActive ? release() : request())}> {isActive ? 'Release' : 'Keep Screen On'} </button> ) : ( <p>Wake lock not supported</p> )} </div> ); } ``` ### Vue Composable ```vue <template> <div> <button @click="toggle" :disabled="!isSupported"> {{ isActive ? 'Release' : 'Keep Screen On' }} </button> </div> </template> <script setup> import { useWakeLock } from 'awake-lock'; const { isActive, request, release, isSupported } = useWakeLock({ onEnabled: () => console.log('Wake lock enabled'), onDisabled: () => console.log('Wake lock disabled'), }); const toggle = () => { isActive.value ? release() : request(); }; </script> ``` ### Angular Service ```typescript import { Component, OnInit } from '@angular/core'; import { WakeLockService } from 'awake-lock'; @Component({ selector: 'app-video-player', template: ` <button (click)="toggle()" [disabled]="!isSupported"> {{ (isActive$ | async) ? 'Release' : 'Keep Screen On' }} </button> `, }) export class VideoPlayerComponent implements OnInit { isActive$ = this.wakeLockService.isActive$; isSupported = this.wakeLockService.isSupported(); constructor(private wakeLockService: WakeLockService) {} async toggle() { const isActive = await this.isActive$.pipe(take(1)).toPromise(); if (isActive) { await this.wakeLockService.release(); } else { await this.wakeLockService.request(); } } } ``` ## Core API ### WakeLock Class ```typescript class WakeLock extends EventEmitter { constructor(options?: WakeLockOptions); request(type: 'screen' | 'system', options?: RequestOptions): Promise<WakeLockSentinel>; release(): Promise<void>; isSupported(): boolean; getStatus(): WakeLockStatus; getSupportedStrategies(): string[]; checkPermissions(type: WakeLockType): Promise<PermissionState | null>; destroy(): void; } ``` ### Options ```typescript interface WakeLockOptions { strategies?: FallbackStrategy[]; // Custom fallback strategies debug?: boolean; // Enable debug logging batteryOptimization?: boolean; // Auto-release on low battery performanceMonitoring?: boolean; // Track performance metrics passive?: boolean; // Fail silently on permission prompts } interface RequestOptions { passive?: boolean; // Override global passive setting timeout?: number; // Request timeout in milliseconds retryAttempts?: number; // Number of retry attempts signal?: AbortSignal; // AbortController signal } ``` ## Fallback Strategy Hierarchy 1. **Screen Wake Lock API** - Modern browsers (Chrome 84+, Edge 84+, Safari 16.4+) 2. **Video Element Strategy** - iOS Safari and older browsers 3. **Audio Context Strategy** - When video fails 4. **Timer Strategy** - Last resort fallback ## Advanced Features ### Passive Mode Prevent disruptive permission prompts: ```typescript const wakeLock = new WakeLock({ passive: true }); // Will fail silently if permission prompt would be shown await wakeLock.request('screen', { passive: true }); ``` ### Battery Optimization ```typescript const wakeLock = new WakeLock({ batteryOptimization: true, performanceMonitoring: true, }); wakeLock.on('battery-change', ({ level, charging }) => { console.log(`Battery: ${level * 100}%, Charging: ${charging}`); }); wakeLock.on('performance', metrics => { console.log('CPU Usage:', metrics.cpuUsage); console.log('Memory Usage:', metrics.memoryUsage); }); ``` ### Custom Fallback Strategies ```typescript class CustomStrategy implements FallbackStrategy { name = 'custom-strategy'; priority = 5; isSupported(): boolean { return /* your support detection */; } async request(type: WakeLockType): Promise<WakeLockSentinel> { // Your implementation } } const wakeLock = new WakeLock({ strategies: [new CustomStrategy()], }); ``` ### Event System ```typescript wakeLock.on('enabled', ({ type, strategy }) => { console.log(`Wake lock enabled: ${type} via ${strategy}`); }); wakeLock.on('disabled', ({ type, reason }) => { console.log(`Wake lock disabled: ${type} (${reason})`); }); wakeLock.on('error', ({ error, strategy }) => { console.error(`Wake lock error in ${strategy}:`, error); }); wakeLock.on('fallback', ({ from, to, reason }) => { console.log(`Fallback from ${from} to ${to}: ${reason}`); }); ``` ## Framework Integrations ### React ```typescript // Basic usage const { isActive, request, release } = useWakeLock(); // With auto-request const wakeLock = useWakeLock({ autoRequest: true, type: 'screen' }); // With context <WakeLockProvider options={{ debug: true }}> <App /> </WakeLockProvider> ``` ### Vue ```typescript // Composable const { isActive, request, release } = useWakeLock(); // Plugin app.use(WakeLockPlugin, { debug: true }); // Directive <div v-wake-lock="{ autoRequest: true }"> Video content </div> ``` ### Angular ```typescript // Service injection constructor(private wakeLockService: WakeLockService) {} // Module @NgModule({ imports: [WakeLockModule], providers: [ ...provideWakeLock({ debug: true }) ] }) // Directive <div wakeLock [wakeLockAutoRequest]="true"> Video content </div> ``` ## Browser Support | Browser | Screen Wake Lock API | Video Fallback | Audio Fallback | Timer Fallback | | ------------- | -------------------- | -------------- | -------------- | -------------- | | Chrome 84+ | ✅ | ✅ | ✅ | ✅ | | Edge 84+ | ✅ | ✅ | ✅ | ✅ | | Safari 16.4+ | ✅ | ✅ | ✅ | ✅ | | Safari < 16.4 | ❌ | ✅ | ✅ | ✅ | | Firefox | ❌ | ✅ | ✅ | ✅ | | Mobile Safari | ❌ | ✅ | ✅ | ✅ | ## Performance - **Bundle Size**: 23KB gzipped (excellent for the feature set) - **Runtime Overhead**: Minimal CPU and memory usage - **Battery Impact**: Optimized with automatic release on low battery - **Startup Time**: < 50ms initialization - **Framework Support**: Optional peer dependencies (no forced bundle size increase) ## Security & Privacy - No data collection or tracking - Respects user permission preferences - Automatic cleanup on page unload - CSP (Content Security Policy) compatible ## Testing The library includes a comprehensive test suite with **25/25 tests passing** using Vitest: ```bash # Run tests pnpm test # Run tests in watch mode pnpm run test:watch # Run tests with UI pnpm run test:ui ``` ## Development ```bash # Clone repository git clone https://github.com/Emmanuelnoi/awake-lock.git # Install dependencies (using pnpm) pnpm install # Run development build with watch mode pnpm run dev # Run tests pnpm test # Build library pnpm run build # Run linting pnpm run lint # Type checking pnpm run typecheck # Format code pnpm run format ``` ## Version History ### v1.0.0 (Production Ready! 🎉) **Major Features:** - ✅ Complete wake lock system with 4 fallback strategies - ✅ Framework integrations for React, Vue, and Angular - ✅ TypeScript with strict mode and comprehensive type safety - ✅ 25/25 tests passing with Vitest - ✅ Safe peer dependency architecture (no framework conflicts) - ✅ pnpm package management with optimized builds - ✅ Battery optimization and performance monitoring - ✅ MIT license and production-ready package metadata **Technical Improvements:** - Migrated from Jest to Vitest for better performance - Migrated from npm to pnpm for faster installs - Optimized bundle size: 23KB gzipped - ESM, CJS, and UMD builds - Professional build system with Rollup - ESLint and Prettier configuration ## License MIT License - see [LICENSE](LICENSE) file for details. ## Support - 🐛 [Report bugs](https://github.com/Emmanuelnoi/awake-lock/issues) - 💡 [Request features](https://github.com/Emmanuelnoi/awake-lock/issues) - 📖 [Documentation](https://github.com/Emmanuelnoi/awake-lock/wiki) - 💬 [Discussions](https://github.com/Emmanuelnoi/awake-lock/discussions) --- Made by [Emmanuel Noi](https://github.com/Emmanuelnoi)