Package Exports
- awake-lock
- awake-lock/core
Readme
AwakeLock 🔋
A comprehensive, framework-agnostic TypeScript library for preventing device sleep with intelligent fallback strategies, battery optimization, and performance monitoring.
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
# Using npm
npm install awake-lock
# Using pnpm (recommended)
pnpm add awake-lock
# Using yarn
yarn add awake-lockPackage Structure
Quick Start
Vanilla JavaScript/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
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
<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
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
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
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
- Screen Wake Lock API - Modern browsers (Chrome 84+, Edge 84+, Safari 16.4+)
- Video Element Strategy - iOS Safari and older browsers
- Audio Context Strategy - When video fails
- Timer Strategy - Last resort fallback
Advanced Features
Passive Mode
Prevent disruptive permission prompts:
const wakeLock = new WakeLock({ passive: true });
// Will fail silently if permission prompt would be shown
await wakeLock.request('screen', { passive: true });Battery Optimization
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
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
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
// 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
// Composable
const { isActive, request, release } = useWakeLock();
// Plugin
app.use(WakeLockPlugin, { debug: true });
// Directive
<div v-wake-lock="{ autoRequest: true }">
Video content
</div>Angular
// 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:
# Run tests
pnpm test
# Run tests in watch mode
pnpm run test:watch
# Run tests with UI
pnpm run test:uiDevelopment
# 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 formatVersion 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 file for details.
Support
Made by Emmanuel Noi