[
  {
    "path": ".gitignore",
    "content": ".DS_Store\nnode_modules\n/dist\n# local env files\n.env.local\n.env.*.local\n\n# Log files\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Editor directories and files\n.idea\n.vscode\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw*\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2018 Filip Rakowski\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"
  },
  {
    "path": "README.md",
    "content": "# Vue Offline\n\nThis library allows you to enhance offline capabilities of your Vue.js application. It's especially useful when you're building offline-first Progressive Web Apps or just want to inform your users that they lost internet connection. \n\n**TL;DR** Adds `isOnline` `isOffline` data properties, `online`, `offline` events via global mixin and enables offline storage via `Vue.$offlineStorage` based on Local Storage\n\n- [Installation](#installation)\n- [Capabilities](#capabilities)\n    - [VueOfflineMixin](#vueofflinemixin)\n    - [VueOfflineStorage](#vueofflinestorage)\n\nInitially made for [Vue Storefront](https://github.com/DivanteLtd/vue-storefront)\n\n## Installation\nTo install this package as a plugin just type:\n````\nnpm install vue-offline --save\n````\n\nand add it into your application with\n````js\nimport VueOffline from 'vue-offline'\n\nVue.use(VueOffline)\n````\n\n## Capabilities\nThis plugin contains two features:\n\n### VueOfflineMixin\nGlobal mixin that'll add following properties to every component in your application:\n\n- `isOnline` & `isOffline` data properties\n````html\n<template>\n    <p v-if=\"isOnline\">This part will be visible only if user is online</p>\n    <p v-if=\"isOffline\">This part will be visible only if user is offline</p>\n</template>\n````\n````js\nexport default {\n    name: 'MyComponent',\n    computed: {\n        networkStatus () {\n            return this.isOnline ? 'My network is fine' : 'I am offline'\n        }\n    }\n}\n````\n- `online` and `offline` events in every component\n````js\nexport default {\n    name: 'MyComponent',\n    mounted () {\n        this.$on('offline', () => {\n            alert('You are offline! The website will not work')\n        })\n    }\n}\n````\n\n### Additional configuration\n\nBy default `VueOfflineMixin` is injected into every component which may be a cause of potential performance problems. You can disable this behavior by setting plugin option `mixin` to `false`. \n````js\nVue.use(VueOffline, {\n    mixin: false\n})\n````\n\nYou can still make use of `VueOfflineMixin` by injecting it directly into your components:\n````js \nimport { VueOfflineMixin } from 'vue-offline'\n\nexport default {\n    name: 'MyComponent',\n    mixins: [VueOfflineMixin],\n    computed: {\n        networkStatus () {\n            return this.isOnline ? 'My network is fine' : 'I am offline'\n        }\n    },\n    mounted () {\n        this.$on('offline', () => {\n            alert('You are offline! The website will not work')\n        })\n    }\n}\n````\n### VueOfflineStorage \n Offline storage that uses [local storage](https://developer.mozilla.org/pl/docs/Web/API/Window/localStorage) to persist data for offline usage and caching. It's a perfect choice for offline-first PWA. You can use it as a fallback for failed network requests or a local cache. \n\nThe storage object has following properties: \n- `set(key, value)` - puts (or updates if already exists) `value` into storage under key `key`.\n- `get(key)` - returns value stored under key `key`\n- `keys` - return array of keys existing in your offline storage\n\nTo use this storage inside your app you can either\n-  use `this.$offlineStorage` from Vue instance property in your components:\n````js\nexport default {\n    methods: {\n        getUserData () {\n            if (this.isOnline) {\n                // make network request that returns 'userData' object\n                this.appData = userData\n                this.$offlineStorage.set('user', userData)\n            } else {\n                this.appData = this.$offlineStorage.get('user')\n            }\n        }\n    }\n}\n````\n- import the `VueOfflineStorage` instance if you want to use it somewhere else (e.g. Vuex store)\n````js\nimport { VueOfflineStorage } from 'vue-offline'\n\nconst cachedData = VueOfflineStorage.get('cached-data')\n\n````\n### Additional configuration\n\nBy default `VueofflineStorage` reference is included into every Vue component. You can disable this behavior by setting plugin option `storage` to `false`. \n````js\nVue.use(VueOffline, {\n    storage: false\n})\n````\n\nYou can still make use of `VueOfflineStorage` by importing it directly into your components:\n````js \nimport { VueOfflineStorage } from 'vue-offline'\n\nexport default {\n    name: 'MyComponent',\n    methods: {\n        getUserData () {\n            if (this.isOnline) {\n                // make network request that returns 'userData' object\n                this.appData = userData\n                VueOfflineStorage.set('user', userData)\n            } else {\n                this.appData = VueOfflineStorage.get('user')\n            }\n        }\n    }\n}\n````\n"
  },
  {
    "path": "lib/vue-offline.js",
    "content": "(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"vue-offline\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"vue-offline\"] = factory();\n\telse\n\t\troot[\"vue-offline\"] = factory();\n})(window, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// define __esModule on exports\n/******/ \t__webpack_require__.r = function(exports) {\n/******/ \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n/******/ \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n/******/ \t\t}\n/******/ \t\tObject.defineProperty(exports, '__esModule', { value: true });\n/******/ \t};\n/******/\n/******/ \t// create a fake namespace object\n/******/ \t// mode & 1: value is a module id, require it\n/******/ \t// mode & 2: merge all properties of value into the ns\n/******/ \t// mode & 4: return value when already ns object\n/******/ \t// mode & 8|1: behave like require\n/******/ \t__webpack_require__.t = function(value, mode) {\n/******/ \t\tif(mode & 1) value = __webpack_require__(value);\n/******/ \t\tif(mode & 8) return value;\n/******/ \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n/******/ \t\tvar ns = Object.create(null);\n/******/ \t\t__webpack_require__.r(ns);\n/******/ \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n/******/ \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n/******/ \t\treturn ns;\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = \"./src/index.js\");\n/******/ })\n/************************************************************************/\n/******/ ({\n\n/***/ \"./src/index.js\":\n/*!**********************!*\\\n  !*** ./src/index.js ***!\n  \\**********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = exports.VueOfflinePlugin = exports.VueOfflineStorage = exports.VueOfflineMixin = void 0;\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n/* ----------------------- Mixin ------------------------ */\n\n/** This mixin adds:\n * - `isOnline`, `isOffline` data properties\n * - `online`, `offline` in-component events \n * */\nvar VueOfflineMixin = {\n  data: function data() {\n    return {\n      isOnline: false,\n      isOffline: false\n    };\n  },\n  mounted: function mounted() {\n    var _this = this;\n\n    if (typeof window !== 'undefined') {\n      navigator.onLine ? this.isOnline = true : this.isOffline = true;\n\n      var onlineHandler = function onlineHandler() {\n        _this.$emit('online');\n\n        _this.isOnline = true;\n        _this.isOffline = false;\n      };\n\n      var offlineHandler = function offlineHandler() {\n        _this.$emit('offline');\n\n        _this.isOffline = true;\n        _this.isOnline = false;\n      };\n\n      window.addEventListener('online', onlineHandler);\n      window.addEventListener('offline', offlineHandler);\n      this.$once('hook:beforeDestroy', function () {\n        window.removeEventListener('online', onlineHandler);\n        window.removeEventListener('offline', offlineHandler);\n      });\n    }\n  }\n};\n/* ----------------------- Storage ------------------------ */\n\nexports.VueOfflineMixin = VueOfflineMixin;\n\nfunction _addKey(newKey) {\n  var keys = JSON.parse(localStorage.getItem('VueOfflineStorageKeys')) || [];\n  if (!keys.includes(newKey)) keys.push(newKey);\n  localStorage.setItem('VueOfflineStorageKeys', JSON.stringify(keys));\n}\n/** Offline storage based on localStorage. You can import it and use standalone or register a plugin */\n\n\nvar VueOfflineStorage = {\n  keys: typeof window !== 'undefined' ? localStorage.getItem('VueOfflineStorageKeys') : null,\n  set: function set(key, value) {\n    if (typeof window !== 'undefined') {\n      localStorage.setItem(key, JSON.stringify(value));\n\n      _addKey(key);\n    }\n  },\n  get: function get(key) {\n    return typeof window !== 'undefined' ? JSON.parse(localStorage.getItem(key)) : null;\n  }\n};\n/* ----------------------- Plugin ------------------------ */\n\n/** Registers VueOfflineMixin in whole application giving you access to:\n * - isOnline, isOffline data properties\n * - online, offline in-component events\n */\n\nexports.VueOfflineStorage = VueOfflineStorage;\nvar VueOfflinePlugin = {\n  install: function install(Vue) {\n    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var defaultOptions = {\n      mixin: true,\n      storage: true\n    };\n\n    var pluginOptions = _objectSpread({}, defaultOptions, options);\n\n    if (pluginOptions.storage) Vue.prototype.$offlineStorage = VueOfflineStorage;\n    if (pluginOptions.mixin) Vue.mixin(VueOfflineMixin);\n  }\n};\nexports.VueOfflinePlugin = VueOfflinePlugin;\nvar _default = VueOfflinePlugin;\nexports.default = _default;\n\n/***/ })\n\n/******/ });\n});\n//# sourceMappingURL=vue-offline.js.map"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"vue-offline\",\n  \"version\": \"2.0.8\",\n  \"description\": \"Offline states and storage for Vue.js apps and Progressive Web Apps\",\n  \"main\": \"lib/vue-offline.js\",\n  \"scripts\": {\n    \"build\": \"webpack --env dev && webpack --env build\",\n    \"dev\": \"webpack --progress --colors --watch --env dev\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/filrak/vue-offline.git\"\n  },\n  \"keywords\": [\n    \"vue\",\n    \"pwa\",\n    \"offline\",\n    \"offline storage\"\n  ],\n  \"author\": \"Filip Rakowski\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/filrak/vue-offline/issues\"\n  },\n  \"homepage\": \"https://github.com/filrak/vue-offline\",\n  \"devDependencies\": {\n    \"@babel/cli\": \"^7.0.0-beta.51\",\n    \"@babel/core\": \"^7.0.0-beta.51\",\n    \"@babel/preset-env\": \"^7.0.0-beta.51\",\n    \"babel-eslint\": \"^8.0.3\",\n    \"babel-loader\": \"^8.0.0-beta.4\",\n    \"babel-plugin-add-module-exports\": \"^0.2.1\",\n    \"babel-preset-env\": \"^7.0.0-beta.3\",\n    \"babel-register\": \"^7.0.0-beta.3\",\n    \"chai\": \"^4.1.2\",\n    \"eslint\": \"^5.0.1\",\n    \"eslint-loader\": \"^2.0.0\",\n    \"jsdom\": \"11.11.0\",\n    \"jsdom-global\": \"3.0.2\",\n    \"mocha\": \"^4.0.1\",\n    \"uglifyjs-webpack-plugin\": \"^1.2.7\",\n    \"webpack\": \"^4.12.2\",\n    \"webpack-cli\": \"^3.0.8\",\n    \"yargs\": \"^10.0.3\"\n  }\n}\n"
  },
  {
    "path": "src/index.js",
    "content": "/* ----------------------- Mixin ------------------------ */\n\n/** This mixin adds:\n * - `isOnline`, `isOffline` data properties\n * - `online`, `offline` in-component events \n * */\nexport const VueOfflineMixin = {\n  data () {\n    return {\n      isOnline: false,\n      isOffline: false\n    }\n  },\n  mounted () {\n    if (typeof window !== 'undefined') {\n      navigator.onLine ? this.isOnline = true : this.isOffline = true\n          \n        const onlineHandler = () => {\n          this.$emit('online')\n          this.isOnline = true\n          this.isOffline = false\n        }\n\n        const offlineHandler = () => {\n          this.$emit('offline')\n          this.isOffline = true\n          this.isOnline = false\n        }\n\n        window.addEventListener('online',  onlineHandler)\n        window.addEventListener('offline',  offlineHandler)\n        \n        this.$once('hook:beforeDestroy', () => {\n          window.removeEventListener('online', onlineHandler)\n          window.removeEventListener('offline', offlineHandler)\n        })\n      }\n  }\n}\n\n/* ----------------------- Storage ------------------------ */\n\nfunction _addKey (newKey) {\n  let keys = JSON.parse(localStorage.getItem('VueOfflineStorageKeys')) || []\n  if (!keys.includes(newKey)) keys.push(newKey)\n  localStorage.setItem('VueOfflineStorageKeys', JSON.stringify(keys))\n}\n\n/** Offline storage based on localStorage. You can import it and use standalone or register a plugin */\nexport const VueOfflineStorage = {\n  keys: typeof window !== 'undefined' ? localStorage.getItem('VueOfflineStorageKeys') : null,\n  set (key, value) {\n    if ( typeof window !== 'undefined' ) {\n    localStorage.setItem(key, JSON.stringify(value))\n    _addKey(key)\n    }\n  },\n  get (key) {\n    return typeof window !== 'undefined' ? JSON.parse(localStorage.getItem(key)) : null\n  }\n}\n\n/* ----------------------- Plugin ------------------------ */\n\n/** Registers VueOfflineMixin in whole application giving you access to:\n * - isOnline, isOffline data properties\n * - online, offline in-component events\n */\nexport const VueOfflinePlugin = {\n  install (Vue, options = {}) {\n    const defaultOptions = {\n      mixin: true,\n      storage: true\n    };\n\n    const pluginOptions = {\n      ...defaultOptions,\n      ...options\n    }\n    if (pluginOptions.storage) Vue.prototype.$offlineStorage = VueOfflineStorage\n    if (pluginOptions.mixin) Vue.mixin(VueOfflineMixin)\n  }\n}\n\nexport default VueOfflinePlugin"
  },
  {
    "path": "webpack.config.js",
    "content": "/* global __dirname, require, module*/\n\nconst webpack = require('webpack');\nconst path = require('path');\nconst env = require('yargs').argv.env; // use --env with webpack 2\nconst pkg = require('./package.json');\n\nlet libraryName = pkg.name;\n\nlet outputFile, mode;\n\nif (env === 'build') {\n  mode = 'production';\n  outputFile = libraryName + '.min.js';\n} else {\n  mode = 'development';\n  outputFile = libraryName + '.js';\n}\n\nconst config = {\n  mode: mode,\n  entry: __dirname + '/src/index.js',\n  devtool: 'source-map',\n  output: {\n    path: __dirname + '/lib',\n    filename: outputFile,\n    library: libraryName,\n    libraryTarget: 'umd',\n    umdNamedDefine: true\n  },\n  module: {\n    rules: [\n      {\n        test: /(\\.jsx|\\.js)$/,\n        loader: 'babel-loader',\n        options: {\n          presets: ['@babel/preset-env']\n        },\n        exclude: /(node_modules|bower_components)/\n      }\n    ]\n  },\n  resolve: {\n    modules: [path.resolve('./node_modules'), path.resolve('./src')],\n    extensions: ['.json', '.js']\n  }\n};\n\nmodule.exports = config;\n"
  }
]