react-simple-channel
Version:
Lightweight and reactive tab-to-tab communication tool for React & non-React contexts. 一个轻量的 React 多标签页通信工具,支持传统函数和 Hook 两种方式。
105 lines (101 loc) • 4.45 kB
JavaScript
var _class;
function _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); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _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); }
/**
* 广播同步工具,非 hooks 场景下使用
*/
import { BroadcastChannel } from "broadcast-channel";
import { debounce, throttle } from "./func";
/**
* 广播同步工具(单例模式)
* 用于跨标签页同步状态,支持监听远程/本地更新
*/
export var BroadcastSync = /*#__PURE__*/function () {
function BroadcastSync(channelName, options) {
var _this = this;
_classCallCheck(this, BroadcastSync);
_defineProperty(this, "channel", void 0);
_defineProperty(this, "callbacks", new Set());
// 包装后的发送函数
_defineProperty(this, "postMessageFn", void 0);
this.channelName = channelName;
this.options = options;
this.channel = new BroadcastChannel(channelName);
this.channel.onmessage = function (msg) {
_this.callbacks.forEach(function (cb) {
return cb(msg, true);
}); // fromRemote = true
};
var rawPost = function rawPost(data) {
_this.callbacks.forEach(function (cb) {
return cb(data, false);
});
_this.channel.postMessage(data);
};
if (options !== null && options !== void 0 && options.debounceMs) {
this.postMessageFn = debounce(rawPost, options.debounceMs);
} else if (options !== null && options !== void 0 && options.throttleMs) {
this.postMessageFn = throttle(rawPost, options.throttleMs);
} else {
this.postMessageFn = rawPost;
}
}
/**
* 获取指定频道的单例
*/
_createClass(BroadcastSync, [{
key: "addEventListener",
value:
/**
* 添加监听器
*/
function addEventListener(callback) {
this.callbacks.add(callback);
return this;
}
/**
* 移除监听器
*/
}, {
key: "removeEventListener",
value: function removeEventListener(callback) {
this.callbacks.delete(callback);
return this;
}
/**
* 发送数据,并触发本地回调(fromRemote: false)
*/
}, {
key: "post",
value: function post(data) {
this.postMessageFn(data);
return this;
}
/**
* 关闭通道(手动销毁该频道)
*/
}, {
key: "close",
value: function close() {
this.channel.close();
BroadcastSync.instances.delete(this.channelName);
return this;
}
}], [{
key: "query",
value: function query(channelName, options) {
if (!this.instances.has(channelName)) {
this.instances.set(channelName, new BroadcastSync(channelName, options));
}
return this.instances.get(channelName);
}
}]);
return BroadcastSync;
}();
_class = BroadcastSync;
_defineProperty(BroadcastSync, "instances", new Map());