multi-tab-sync
Version:
A powerful multi-tab data synchronization library for Vue.js and browser extensions
52 lines (39 loc) • 21.9 kB
JavaScript
"use strict";
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
(this["webpackChunkMultiTabSync"] = this["webpackChunkMultiTabSync"] || []).push([["core"],{
/***/ "./src/core/BroadcastChannelStrategy.js":
/*!**********************************************!*\
!*** ./src/core/BroadcastChannelStrategy.js ***!
\**********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ BroadcastChannelStrategy: () => (/* binding */ BroadcastChannelStrategy),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nfunction _typeof(o) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o; }, _typeof(o); }\nfunction _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError(\"Cannot call a class as a function\"); }\nfunction _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, \"value\" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }\nfunction _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, \"prototype\", { writable: !1 }), e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == _typeof(i) ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != _typeof(i)) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\nvar BroadcastChannelStrategy = /*#__PURE__*/function () {\n function BroadcastChannelStrategy(options) {\n _classCallCheck(this, BroadcastChannelStrategy);\n this.options = options;\n this.channel = new BroadcastChannel(\"multi-tab-sync-channel\");\n this.listeners = new Set();\n }\n return _createClass(BroadcastChannelStrategy, [{\n key: \"send\",\n value: function send(message) {\n this.channel.postMessage(message);\n }\n }, {\n key: \"onMessage\",\n value: function onMessage(callback) {\n var _this = this;\n var handler = function handler(event) {\n if (event.data && event.data.source === \"multi-tab-sync\") {\n callback(event.data);\n }\n };\n this.channel.addEventListener(\"message\", handler);\n this.listeners.add(handler);\n return function () {\n _this.channel.removeEventListener(\"message\", handler);\n _this.listeners[\"delete\"](handler);\n };\n }\n }, {\n key: \"destroy\",\n value: function destroy() {\n var _this2 = this;\n this.listeners.forEach(function (handler) {\n _this2.channel.removeEventListener(\"message\", handler);\n });\n this.listeners.clear();\n this.channel.close();\n }\n }]);\n}();\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (BroadcastChannelStrategy);\n\n//# sourceURL=webpack://MultiTabSync/./src/core/BroadcastChannelStrategy.js?\n}");
/***/ }),
/***/ "./src/core/ChromeExtensionStrategy.js":
/*!*********************************************!*\
!*** ./src/core/ChromeExtensionStrategy.js ***!
\*********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ChromeExtensionStrategy: () => (/* binding */ ChromeExtensionStrategy),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nfunction _typeof(o) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o; }, _typeof(o); }\nfunction _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError(\"Cannot call a class as a function\"); }\nfunction _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, \"value\" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }\nfunction _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, \"prototype\", { writable: !1 }), e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == _typeof(i) ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != _typeof(i)) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\nvar ChromeExtensionStrategy = /*#__PURE__*/function () {\n function ChromeExtensionStrategy(options) {\n _classCallCheck(this, ChromeExtensionStrategy);\n this.options = options;\n this.listeners = new Set();\n this.init();\n }\n return _createClass(ChromeExtensionStrategy, [{\n key: \"init\",\n value: function init() {\n if (typeof chrome !== \"undefined\" && chrome.runtime && chrome.runtime.onMessage) {\n chrome.runtime.onMessage.addListener(this.handleChromeMessage.bind(this));\n }\n }\n }, {\n key: \"handleChromeMessage\",\n value: function handleChromeMessage(message, sender, sendResponse) {\n if (message && message.source === \"multi-tab-sync\") {\n this.listeners.forEach(function (callback) {\n return callback(message);\n });\n }\n }\n }, {\n key: \"send\",\n value: function send(message) {\n if (typeof chrome !== \"undefined\" && chrome.runtime && chrome.runtime.sendMessage) {\n chrome.runtime.sendMessage(message);\n }\n }\n }, {\n key: \"onMessage\",\n value: function onMessage(callback) {\n var _this = this;\n this.listeners.add(callback);\n return function () {\n return _this.listeners[\"delete\"](callback);\n };\n }\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.listeners.clear();\n }\n }]);\n}();\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChromeExtensionStrategy);\n\n//# sourceURL=webpack://MultiTabSync/./src/core/ChromeExtensionStrategy.js?\n}");
/***/ }),
/***/ "./src/core/LocalStorageStrategy.js":
/*!******************************************!*\
!*** ./src/core/LocalStorageStrategy.js ***!
\******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ LocalStorageStrategy: () => (/* binding */ LocalStorageStrategy),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nfunction _typeof(o) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o; }, _typeof(o); }\nfunction _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError(\"Cannot call a class as a function\"); }\nfunction _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, \"value\" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }\nfunction _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, \"prototype\", { writable: !1 }), e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == _typeof(i) ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != _typeof(i)) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\nvar LocalStorageStrategy = /*#__PURE__*/function () {\n function LocalStorageStrategy(options) {\n _classCallCheck(this, LocalStorageStrategy);\n this.options = options;\n this.listeners = new Set();\n this.init();\n }\n return _createClass(LocalStorageStrategy, [{\n key: \"init\",\n value: function init() {\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"storage\", this.handleStorageEvent.bind(this));\n }\n }\n }, {\n key: \"handleStorageEvent\",\n value: function handleStorageEvent(event) {\n if (event.key && event.key.startsWith(this.options.prefix)) {\n var message = {\n type: event.newValue === null ? \"REMOVE\" : \"SET\",\n key: event.key,\n value: event.newValue,\n source: \"multi-tab-sync\"\n };\n this.listeners.forEach(function (callback) {\n return callback(message);\n });\n }\n }\n }, {\n key: \"send\",\n value: function send(message) {\n if (message.type === \"SET\") {\n localStorage.setItem(message.key, message.value);\n } else if (message.type === \"REMOVE\") {\n localStorage.removeItem(message.key);\n }\n // storage事件会自动触发,不需要额外处理\n }\n }, {\n key: \"onMessage\",\n value: function onMessage(callback) {\n var _this = this;\n this.listeners.add(callback);\n return function () {\n return _this.listeners[\"delete\"](callback);\n };\n }\n }, {\n key: \"destroy\",\n value: function destroy() {\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"storage\", this.handleStorageEvent.bind(this));\n }\n this.listeners.clear();\n }\n }]);\n}();\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (LocalStorageStrategy);\n\n//# sourceURL=webpack://MultiTabSync/./src/core/LocalStorageStrategy.js?\n}");
/***/ }),
/***/ "./src/core/SyncManager.js":
/*!*********************************!*\
!*** ./src/core/SyncManager.js ***!
\*********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ SyncManager: () => (/* binding */ SyncManager),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _BroadcastChannelStrategy_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BroadcastChannelStrategy.js */ \"./src/core/BroadcastChannelStrategy.js\");\n/* harmony import */ var _LocalStorageStrategy_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./LocalStorageStrategy.js */ \"./src/core/LocalStorageStrategy.js\");\n/* harmony import */ var _ChromeExtensionStrategy_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ChromeExtensionStrategy.js */ \"./src/core/ChromeExtensionStrategy.js\");\nfunction _typeof(o) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o; }, _typeof(o); }\nfunction ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }\nfunction _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }\nfunction _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }\nfunction _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError(\"Cannot call a class as a function\"); }\nfunction _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, \"value\" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }\nfunction _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, \"prototype\", { writable: !1 }), e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == _typeof(i) ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != _typeof(i)) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\n\n\n\nvar SyncManager = /*#__PURE__*/function () {\n function SyncManager() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n _classCallCheck(this, SyncManager);\n this.options = _objectSpread({\n prefix: \"mts_\",\n useBroadcastChannel: true,\n useLocalStorage: true,\n useChromeExtension: false,\n serialization: {\n serialize: JSON.stringify,\n deserialize: JSON.parse\n }\n }, options);\n this.strategies = [];\n this.isSupported = true;\n this.supportMessage = \"\";\n this.eventListeners = new Set();\n this.init();\n }\n return _createClass(SyncManager, [{\n key: \"init\",\n value: function init() {\n var _this = this;\n try {\n // 检测基本支持\n if (typeof window === \"undefined\") {\n throw new Error(\"Window object is not available\");\n }\n\n // 初始化策略\n if (this.options.useBroadcastChannel && typeof BroadcastChannel !== \"undefined\") {\n this.strategies.push(new _BroadcastChannelStrategy_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"](this.options));\n this.supportMessage = \"Using BroadcastChannel for synchronization\";\n }\n if (this.options.useLocalStorage && typeof localStorage !== \"undefined\") {\n this.strategies.push(new _LocalStorageStrategy_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"](this.options));\n if (!this.supportMessage) {\n this.supportMessage = \"Using localStorage for synchronization\";\n }\n }\n if (this.options.useChromeExtension && typeof chrome !== \"undefined\" && chrome.runtime && chrome.runtime.sendMessage) {\n this.strategies.push(new _ChromeExtensionStrategy_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"](this.options));\n this.supportMessage += \" + Chrome Extension API\";\n }\n if (this.strategies.length === 0) {\n throw new Error(\"No synchronization strategy available\");\n }\n\n // 初始化事件监听\n this.strategies.forEach(function (strategy) {\n strategy.onMessage(function (message) {\n _this.handleIncomingMessage(message);\n });\n });\n } catch (error) {\n this.isSupported = false;\n this.supportMessage = \"Synchronization not supported: \".concat(error.message);\n console.warn(this.supportMessage);\n }\n }\n }, {\n key: \"handleIncomingMessage\",\n value: function handleIncomingMessage(message) {\n this.eventListeners.forEach(function (listener) {\n try {\n listener(message);\n } catch (error) {\n console.error(\"Error in event listener:\", error);\n }\n });\n }\n }, {\n key: \"on\",\n value: function on(event, callback) {\n var _this2 = this;\n this.eventListeners.add(callback);\n return function () {\n return _this2.eventListeners[\"delete\"](callback);\n };\n }\n }, {\n key: \"off\",\n value: function off(event, callback) {\n this.eventListeners[\"delete\"](callback);\n }\n }, {\n key: \"set\",\n value: function set(key, value) {\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n if (!this.isSupported) return false;\n var message = {\n type: \"SET\",\n key: this.options.prefix + key,\n value: this.options.serialization.serialize(value),\n timestamp: Date.now(),\n expiry: options.expiry ? Date.now() + options.expiry : null,\n source: \"multi-tab-sync\"\n };\n return this.broadcastMessage(message);\n }\n }, {\n key: \"get\",\n value: function get(key) {\n if (!this.isSupported) return null;\n var prefixedKey = this.options.prefix + key;\n try {\n var item = localStorage.getItem(prefixedKey);\n if (!item) return null;\n var data = this.options.serialization.deserialize(item);\n\n // 检查过期\n if (data.expiry && Date.now() > data.expiry) {\n this.remove(key);\n return null;\n }\n return data.value;\n } catch (error) {\n console.error(\"Failed to get data:\", error);\n return null;\n }\n }\n }, {\n key: \"remove\",\n value: function remove(key) {\n if (!this.isSupported) return false;\n var message = {\n type: \"REMOVE\",\n key: this.options.prefix + key,\n source: \"multi-tab-sync\"\n };\n\n // 从localStorage删除\n try {\n localStorage.removeItem(message.key);\n } catch (error) {\n console.error(\"Failed to remove from localStorage:\", error);\n }\n return this.broadcastMessage(message);\n }\n }, {\n key: \"clear\",\n value: function clear() {\n if (!this.isSupported) return false;\n var message = {\n type: \"CLEAR\",\n prefix: this.options.prefix,\n source: \"multi-tab-sync\"\n };\n\n // 清空localStorage中带前缀的项\n try {\n var keysToRemove = [];\n for (var i = 0; i < localStorage.length; i++) {\n var key = localStorage.key(i);\n if (key.startsWith(this.options.prefix)) {\n keysToRemove.push(key);\n }\n }\n keysToRemove.forEach(function (key) {\n return localStorage.removeItem(key);\n });\n } catch (error) {\n console.error(\"Failed to clear localStorage:\", error);\n }\n return this.broadcastMessage(message);\n }\n }, {\n key: \"broadcastMessage\",\n value: function broadcastMessage(message) {\n var success = true;\n this.strategies.forEach(function (strategy) {\n try {\n strategy.send(message);\n } catch (error) {\n console.error(\"Strategy \".concat(strategy.constructor.name, \" failed:\"), error);\n success = false;\n }\n });\n return success;\n }\n }, {\n key: \"getAll\",\n value: function getAll() {\n if (!this.isSupported) return {};\n var result = {};\n try {\n for (var i = 0; i < localStorage.length; i++) {\n var key = localStorage.key(i);\n if (key.startsWith(this.options.prefix)) {\n try {\n var item = localStorage.getItem(key);\n var data = this.options.serialization.deserialize(item);\n\n // 检查过期\n if (data.expiry && Date.now() > data.expiry) {\n this.remove(key.substring(this.options.prefix.length));\n continue;\n }\n result[key.substring(this.options.prefix.length)] = data;\n } catch (error) {\n console.error(\"Failed to parse data for key:\", key, error);\n }\n }\n }\n } catch (error) {\n console.error(\"Failed to get all data:\", error);\n }\n return result;\n }\n }]);\n}();\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (SyncManager);\n\n//# sourceURL=webpack://MultiTabSync/./src/core/SyncManager.js?\n}");
/***/ })
}]);