{"_id":"@alekstar79/media-tracker","name":"@alekstar79/media-tracker","dist-tags":{"latest":"2.0.0"},"versions":{"2.0.0":{"name":"@alekstar79/media-tracker","version":"2.0.0","description":"Processing media queries via browser API from JavaScript","type":"module","private":false,"main":"./dist-lib/media-tracker.umd.js","module":"./dist-lib/media-tracker.es.js","types":"./dist-lib/index.d.ts","exports":{".":{"import":"./dist-lib/media-tracker.es.js","require":"./dist-lib/media-tracker.umd.js","types":"./dist-lib/index.d.ts"},"./style":"./dist-lib/media-tracker.css"},"keywords":["media-queries","responsive","breakpoints","tracker","typescript","matchmedia"],"author":{"name":"Aleksey Tarasenko","email":"alekstar79@yandex.ru"},"license":"ISC","repository":{"type":"git","url":"git+https://github.com/alekstar79/media-tracker.git"},"homepage":"https://github.com/alekstar79/media-tracker#readme","bugs":{"url":"https://github.com/alekstar79/media-tracker/issues"},"publishConfig":{"access":"public"},"scripts":{"dev":"vite","build":"vite build","build:lib":"vite build --config vite.lib.config.ts","preview":"vite preview","docs":"jsdoc -c jsdoc.config.json","prepublishOnly":"npm run build:lib && npm test","pub:dry-run":"npm run build:lib && npm publish --dry-run","pub:beta":"npm run build:lib && npm publish --tag beta","pub:patch":"npm version patch && npm run build:lib && npm publish","pub:minor":"npm version minor && npm run build:lib && npm publish","pub:major":"npm version major && npm run build:lib && npm publish","test":"echo \"No tests yet\" && exit 0"},"devDependencies":{"@babel/cli":"^7.28.3","@babel/core":"^7.28.5","@babel/preset-env":"^7.28.5","@babel/preset-typescript":"^7.28.5","@types/node":"^24.9.1","docdash":"^2.0.2","jsdoc":"^4.0.2","jsdoc-babel":"^0.5.0","typescript":"^5.0.0","vite-plugin-dts":"^4.5.4","vite":"^5.0.0"},"_id":"@alekstar79/media-tracker@2.0.0","gitHead":"1632966ecd617f559a668ff140b1e511237bc4fe","_nodeVersion":"18.20.3","_npmVersion":"10.7.0","dist":{"integrity":"sha512-mfkLp+4Fk7sq43M4T3fTw8epBwWzYhYnGHGy/w5usFUFFytZKYRh7o4/1gVvUUmpUKDRJkeHNeoybAwD8BjrnA==","shasum":"35f4e45c5ddc389cdbeb054bda5805ea839d4e88","tarball":"https://registry.npmjs.org/@alekstar79/media-tracker/-/media-tracker-2.0.0.tgz","fileCount":7,"unpackedSize":26143,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIG/O2zfRmxaxJGN29xedOk6qxU4d11w4CJmn2Yw5i0usAiBOI6UAtao61EctQeFIvCoS1NfpMGrpicx2Sqp1KmriwQ=="}]},"_npmUser":{"name":"alekstar79","email":"alekstar79@yandex.ru"},"directories":{},"maintainers":[{"name":"alekstar79","email":"alekstar79@yandex.ru"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/media-tracker_2.0.0_1761661070339_0.0010053921443990976"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-28T14:17:50.219Z","2.0.0":"2025-10-28T14:17:50.549Z","modified":"2025-10-28T14:17:50.846Z"},"maintainers":[{"name":"alekstar79","email":"alekstar79@yandex.ru"}],"description":"Processing media queries via browser API from JavaScript","homepage":"https://github.com/alekstar79/media-tracker#readme","keywords":["media-queries","responsive","breakpoints","tracker","typescript","matchmedia"],"repository":{"type":"git","url":"git+https://github.com/alekstar79/media-tracker.git"},"author":{"name":"Aleksey Tarasenko","email":"alekstar79@yandex.ru"},"bugs":{"url":"https://github.com/alekstar79/media-tracker/issues"},"license":"ISC","readme":"# Media Tracker TS\n\n[![NPM](https://img.shields.io/npm/v/@alekstar79/media-tracker.svg)](https://www.npmjs.com/package/@alekstar79/media-tracker)\n[![GitHub repo](https://img.shields.io/badge/github-repo-green.svg?style=flat)](https://github.com/alekstar79/media-tracker)\n[![Typescript](https://img.shields.io/badge/TypeScript-Ready-blue?logo=typescript)]()\n[![License](https://img.shields.io/badge/License-ISC-green)]()\n[![Version](https://img.shields.io/badge/Version-2.0.0-orange)]()\n\nA lightweight, high-performance TypeScript library for tracking media queries and responsive breakpoints in modern web applications.\n\n![Media Tracker TS](review.gif)\n\n## 🎮 Demo\n\nCheck out the live demo: [Media Tracker Demo](https://alekstar79.github.io/media-tracker)\n\nThe demo shows real-time breakpoint tracking with toast notifications and demonstrates all library features in action.\n\n## 🚀 Features\n\n- 🪶 Lightweight - Zero dependencies, minimal footprint\n- 📱 Responsive - Track any breakpoint configuration\n- ⚡ High Performance - Uses native MediaQueryList API with debouncing\n- 🔷 TypeScript - Fully typed with comprehensive documentation\n- 🎯 Precise - Binary search algorithm for optimal breakpoint matching\n- 🛠️ Flexible - Customizable breakpoints and debounce timing\n- 📦 Dual Build - Support for ES modules, CommonJS, and UMD\n\n## 📁 Project Structure\n\n```text\nmedia-tracker/\n├── src/\n│   ├── lib/                 # Library core\n│   │   ├── constants.ts     # Breakpoint constants\n│   │   ├── media-tracker.ts # Main MediaTracker class\n│   │   └── index.ts         # Library entry point\n│   ├── demo/                # Demo application\n│   │   ├── emitter.ts       # Event emitter (demo only)\n│   │   ├── notifications.ts # Toast notifications\n│   │   ├── media-handler.ts # Demo media handler\n│   │   └── index.ts         # Demo entry point\n│   ├── styles/\n│   │   └── style.css        # Demo styles\n│   └── index.html           # Demo HTML\n├── dist/                    # Demo build output\n├── dist-lib/                # Library build output\n└── docs/                    # Generated documentation\n```\n\n## 📦 Installation\n\n**Library Installation:**\n\n```shell\nyarn install @alekstar79/media-traker\n```\n**Development Setup:**\n\n```shell\ngit clone git@github.com:alekstar79/media-tracker.git\ncd media-tracker\nyarn install\n```\n\n## 💻 Usage\n\n### 📄 ES Modules (Recommended)\n\n```ts\nimport { MediaTracker, W768, W1024, W1200 } from 'media-tracker';\n\nconst tracker = MediaTracker.create(\n  [W768, W1024, W1200],\n  (state) => {\n    console.log('Current media state:', state);\n    \n    if (state.width === W768) {\n      // Mobile layout\n    } else if (state.width === W1024) {\n      // Tablet layout  \n    } else if (state.width === W1200) {\n      // Desktop layout\n    }\n  },\n  150 // Optional debounce time (ms)\n)\n```\n\n### 📦 CommonJS\n\n```js\nconst { MediaTracker, W768, W1024 } = require('media-tracker')\n\nconst tracker = MediaTracker.create([W768, W1024], (state) => {\n  console.log('Media state changed:', state)\n})\n```\n\n### 🌐 In Browser (UMD)\n\n```html\n<script src=\"https://unpkg.com/media-tracker/dist-lib/media-tracker.umd.js\"></script>\n<script>\n  const tracker = MediaTracker.create(\n    [MediaTracker.W768, MediaTracker.W1024],\n    function(state) {\n      console.log('Breakpoint:', state)\n    }\n  )\n</script>\n```\n\n## 📊 Available Breakpoints\n\n```ts\nimport {\n  W0,      // 0px    - 📱 Base mobile\n  W240,    // 240px  - 📱 Very small mobile\n  W320,    // 320px  - 📱 Small mobile\n  W480,    // 480px  - 📱 Mobile landscape\n  W640,    // 640px  - 📟 Small tablets\n  W768,    // 768px  - 📟 Tablets\n  W991,    // 991px  - 🖥️ Small desktops\n  W1024,   // 1024px - 🖥️ Desktop screens\n  W1200,   // 1200px - 🖥️ Large desktop\n  W1280,   // 1280px - 🖥️ HD desktop\n  W1728,   // 1728px - 🖥️ Large HD\n  W1920,   // 1920px - 🖥️ Full HD\n  W1980,   // 1980px - 🖥️ Large Full HD\n  W3840,   // 3840px - 📺 4K Ultra HD\n  W4096    // 4096px - 📺 Maximum\n} from 'media-tracker'\n```\n\n## 🔨 Development\n\n🚀 **Start development server:**\n```shell\nyarn dev\n```\n\nStarts Vite development server at http://localhost:3000\n\n📦 **Build for production:**\n```shell\nyarn build        # 🏗️ Build demo application\nyarn build:lib    # 📦 Build library for distribution\n```\n\n👀 **Preview production build:**\n```shell\nyarn preview\n```\n\n📚 **Generate documentation:**\n```shell\nyarn docs\n```\n\n## ⚙️ Configuration\n\n**MediaTracker Options**\n\n| Option         | Type                          | Default  | Description                                     |\n|----------------|-------------------------------|----------|-------------------------------------------------|\n| `widths`       | `number[]`                    | Required | Array of breakpoint widths to track             |\n| `handler`      | `(state: MediaState) => void` | Required | Callback function for media changes             |\n| `debounceTime` | `number`                      | `100`    | Debounce time in milliseconds for resize events |\n\n**MediaState Object**\n\n```ts\ninterface MediaState {\n  width?: number;     // Current viewport width (when exact match)\n  maxWidth?: number;  // Next larger breakpoint  \n  minWidth?: number;  // Next smaller breakpoint\n}\n```\n\n## 📖 API Reference\n\n### MediaTracker Class\n\n  ⚡ Static Methods\n\nMediaTracker.create(widths, handler, debounceTime?)\n\n1. Creates and initializes a new MediaTracker instance\n2. Parameters:\n\n    - widths: number[] - Breakpoint widths to track\n    - handler: (state: MediaState) => void - Change callback\n    - debounceTime?: number - Debounce time (ms), default: 100\n\n3. Returns: MediaTracker instance\n\n  🔧 Instance Methods\n\nsetWidths(widths)\n\n- Updates the breakpoint configuration\n- Parameters: widths: number[] - New breakpoint array\n- Returns: MediaTracker instance (chainable)\n\nsetHandler(handler)\n\n- Updates the change handler function\n- Parameters: handler: (state: MediaState) => void - New callback\n- Returns: MediaTracker instance (chainable)\n\nonTrack()\n\n- Starts tracking media queries and resize events\n- Returns: MediaTracker instance (chainable)\n\nnearestWidths()\n\n- Calculates current media state\n- Returns: MediaState object\n\n## 🔄 Lifecycle\n\n1. 🚀 **Initialization** - Create instance with breakpoints and handler\n2. 📡 **Tracking Start** - Media queries and resize listeners are set up\n3. 🔄 **State Changes** - Handler is called on breakpoint changes\n4. 🧹 **Automatic Cleanup** - Listeners are managed internally\n\n## 🏎️ Performance Tips\n\n1. 🎯 Minimize Breakpoints - Only track breakpoints you actually use\n2. ⏰ Optimize Debounce - Increase debounce time for complex handlers\n3. 🎯 Use Exact Matches - Handler receives exact matches when available\n4. 📦 Batch Updates - Use requestAnimationFrame in complex UIs\n\n```ts\n// ✅ Good: Minimal breakpoints\nMediaTracker.create([W768, W1024, W1200], handler)\n\n// ✅ Better: Increased debounce for heavy operations  \nMediaTracker.create(breakpoints, heavyHandler, 250)\n```\n\n## ❗ Troubleshooting\n\n**Check imports:**\n\n```ts\n// ✅ Correct\nimport { MediaTracker, W768 } from 'media-tracker'\n\n// ❌ Incorrect  \nimport MediaTracker from 'media-tracker'\n```\n\n**Verify breakpoints:**\n\n```ts\n// ✅ Breakpoints must be sorted and unique\nMediaTracker.create([768, 1024, 1200], handler) // ✓ Works\nMediaTracker.create([1200, 768], handler)       // ✓ Auto-sorted\nMediaTracker.create([], handler)                // ❌ Throws error\n```\n\n**Check handler:**\n\n```ts\n// ✅ Handler must be a function\nMediaTracker.create(breakpoints, console.log)               // ✓ Works\nMediaTracker.create(breakpoints, (state) => {/*...*/})      // ✓ Works  \nMediaTracker.create(breakpoints, 'not a function')          // ❌ Throws error\n```\n\n## 🐛 Common Issues\n\n**Handler not called on initial load:**\n\n- MediaTracker automatically calls handler with initial state\n- Check browser console for errors\n\n**Resize events too frequent:**\n\n- Increase debounceTime parameter\n- Default is 100ms, try 150-250ms for better performance\n\n**Breakpoints not matching:**\n\n- Ensure breakpoints are in pixels\n- Verify viewport meta tag in HTML:\n`<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">`\n\n\n## 🌐 Browser Support\n\n| Browser            | Version | Support |\n|--------------------|---------|---------|\n| 🟢 Chrome          | 41+     | ✅ Full  |\n| 🟢 Firefox         | 47+     | ✅ Full  |\n| 🟢 Safari          | 10.1+   | ✅ Full  |\n| 🟢 Edge            | 16+     | ✅ Full  |\n| 🟢 iOS Safari      | 10.3+   | ✅ Full  |\n| 🟢 Android Browser | 56+     | ✅ Full  |\n\n**Required APIs:**\n\n- window.matchMedia (CSSOM View Module)\n- ResizeObserver (for demo features)\n- ES2015+ features (arrow functions, const/let, classes)\n\n\n## 🧩 Polyfills (if needed)\n\nFor older browsers, include these polyfills:\n\n```html\n<!-- matchMedia polyfill -->\n<script src=\"https://cdn.polyfill.io/v3/polyfill.min.js?features=MatchMedia\"></script>\n```\n<div align=\"center\">\n  Built with ❤️ and TypeScript\n</div>\n","readmeFilename":"README.md","_rev":"1-ac9a86d89fa0031eea056781df735f05"}