UNPKG

zustand-yjs

Version:

Zustand Stores with Yjs

372 lines (329 loc) 11.4 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var create = require('zustand'); var react = require('react'); var shallow = require('zustand/shallow'); var Y = require('yjs'); var _extends = require('@babel/runtime/helpers/extends'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n["default"] = e; return Object.freeze(n); } var create__default = /*#__PURE__*/_interopDefaultLegacy(create); var shallow__default = /*#__PURE__*/_interopDefaultLegacy(shallow); var Y__namespace = /*#__PURE__*/_interopNamespace(Y); var _extends__default = /*#__PURE__*/_interopDefaultLegacy(_extends); exports.YDocEnum = void 0; (function (YDocEnum) { YDocEnum[YDocEnum["GUID"] = 0] = "GUID"; YDocEnum[YDocEnum["DOC"] = 1] = "DOC"; YDocEnum[YDocEnum["MOUNT"] = 2] = "MOUNT"; YDocEnum[YDocEnum["UN_MOUNT"] = 3] = "UN_MOUNT"; YDocEnum[YDocEnum["USE_CNT"] = 4] = "USE_CNT"; })(exports.YDocEnum || (exports.YDocEnum = {})); exports.ObserveEnum = void 0; (function (ObserveEnum) { ObserveEnum[ObserveEnum["TYPE"] = 0] = "TYPE"; ObserveEnum[ObserveEnum["OBSERVE"] = 1] = "OBSERVE"; ObserveEnum[ObserveEnum["USE_CNT"] = 2] = "USE_CNT"; })(exports.ObserveEnum || (exports.ObserveEnum = {})); var newStartAwareness = function newStartAwareness(setAwareness) { var startAwareness = function startAwareness(provider) { var awareness = provider.awareness; var updateAwareness = function updateAwareness() { setAwareness(provider, Array.from(awareness.getStates().values())); }; updateAwareness(); awareness.on('update', updateAwareness); return function () { awareness.off('update', updateAwareness); }; }; return startAwareness; }; var useYStore = create__default["default"](function (set, get) { return { yDocs: [], yAwareness: [], observers: [], data: [], update: function update(type, data) { var dataSet = get().data; set({ data: [].concat(dataSet.filter(function (_ref) { var t = _ref[0]; return t !== type; }), [[type, data]]) }); }, listenType: function listenType(type, listen) { var observers = get().observers; var match = observers.find(function (_ref2) { var observer = _ref2[0]; return observer === type; }); if (match) { set({ observers: [].concat(observers.filter(function (obs) { return obs !== match; }), [[match[exports.ObserveEnum.TYPE], match[exports.ObserveEnum.OBSERVE], match[exports.ObserveEnum.USE_CNT] + 1]]) }); } else { type.observe(listen); set({ observers: [].concat(observers, [[type, listen, 1]]) }); } }, unListenType: function unListenType(type) { var observers = get().observers; var match = observers.find(function (_ref3) { var t = _ref3[0]; return t === type; }); if (!match) { console.warn('Type ', type, " wasn't mounted"); return; } var observerCount = match[exports.ObserveEnum.USE_CNT] - 1; if (observerCount > 0) { set({ observers: [].concat(observers.filter(function (obs) { return obs !== match; }), [[match[exports.ObserveEnum.TYPE], match[exports.ObserveEnum.OBSERVE], observerCount]]) }); } else { type.unobserve(match[exports.ObserveEnum.OBSERVE]); set({ observers: [].concat(observers.filter(function (obs) { return obs !== match; })), data: [].concat(get().data.filter(function (_ref4) { var t = _ref4[0]; return t !== type; })) }); } }, unMountYDoc: function unMountYDoc(yDoc) { var yDocs = get().yDocs; var yAwareness = get().yAwareness; var match = yDocs.find(function (_ref5) { var doc = _ref5[1]; return doc === yDoc; }); if (!match) { console.warn('Can not unmount doc ', yDoc.guid, ' . Doc not found'); return; } var observerCount = match[exports.YDocEnum.USE_CNT] - 1; if (observerCount > 0) { set({ yDocs: [].concat(yDocs.filter(function (yDoc) { return yDoc !== match; }), [[match[exports.YDocEnum.GUID], match[exports.YDocEnum.DOC], match[exports.YDocEnum.MOUNT], match[exports.YDocEnum.UN_MOUNT], observerCount]]) }); } else { var unMount = match[exports.YDocEnum.UN_MOUNT]; if (unMount) unMount(); set({ yDocs: yDocs.filter(function (yDoc) { return yDoc !== match; }), yAwareness: yAwareness.filter(function (_ref6) { var yDocName = _ref6[0]; return yDocName !== match[0]; }) }); } }, mountYDoc: function mountYDoc(yDoc, mount) { var yDocs = get().yDocs; var yAwareness = get().yAwareness; var match = yDocs.find(function (_ref7) { var name = _ref7[0]; return name === yDoc.guid; }); if (match) { if (match[exports.YDocEnum.MOUNT] !== mount) { console.warn('A different connection function was already provided for ', match[exports.YDocEnum.GUID], '. This unMount function will be ignored'); } match[exports.YDocEnum.USE_CNT]++; set({ yDocs: [].concat(yDocs.filter(function (_ref8) { var name = _ref8[0]; return name !== yDoc.guid; }), [match]) }); } else { var unMount = mount(yDoc, newStartAwareness(function (protocol, changes) { set({ yAwareness: [].concat(yAwareness, [[yDoc.guid, protocol.awareness, changes]]) }); })); set({ yDocs: [].concat(yDocs, [[yDoc.guid, yDoc, mount, unMount, 1]]) }); } } }; }); var useYStore$1 = useYStore; var useYObserve = function useYObserve(yType, serialize) { var _useYStore = useYStore$1(function (state) { return [state.listenType, state.unListenType, state.update]; }, shallow__default["default"]), listen = _useYStore[0], unListen = _useYStore[1], update = _useYStore[2]; react.useEffect(function () { listen(yType, function () { return update(yType, serialize()); }); update(yType, serialize()); return function () { return unListen(yType); }; }, []); }; var useYObserve$1 = useYObserve; var useYArray = function useYArray(yArray) { useYObserve$1(yArray, function () { return yArray.toArray(); }); var dataSet = useYStore$1(function (state) { return state.data; }); var data = react.useMemo(function () { var match = dataSet.find(function (_ref) { var type = _ref[0]; return type === yArray; }); if (!match) return []; return match[1]; }, [yArray, dataSet]); var noBinding = function noBinding(funcKey) { return function () { throw new Error("Y.Array#" + funcKey.toString() + " is not implemented"); }; }; return { forEach: yArray.forEach ? yArray.forEach.bind(yArray) : noBinding('forEach'), map: yArray.map ? yArray.map.bind(yArray) : noBinding('map'), slice: yArray.slice ? yArray.slice.bind(yArray) : noBinding('slice'), get: yArray.get ? yArray.get.bind(yArray) : noBinding('get'), delete: yArray.delete ? yArray.delete.bind(yArray) : noBinding('delete'), unshift: yArray.unshift ? yArray.unshift.bind(yArray) : noBinding('unshift'), push: yArray.push ? yArray.push.bind(yArray) : noBinding('push'), insert: yArray.insert ? yArray.insert.bind(yArray) : noBinding('insert'), data: data }; }; var useYArray$1 = useYArray; var useYMap = function useYMap(yMap) { useYObserve$1(yMap, function () { return yMap.toJSON(); }); var dataSet = useYStore$1(function (state) { return state.data; }); var data = react.useMemo(function () { var match = dataSet.find(function (_ref) { var type = _ref[0]; return type === yMap; }); if (!match) return {}; return match[1]; }, [yMap, dataSet]); var noBinding = function noBinding(funcKey) { return function () { throw new Error("Y.Map#" + funcKey.toString() + " is not implemented"); }; }; return { keys: yMap.keys ? yMap.keys.bind(yMap) : noBinding('keys'), values: yMap.values ? yMap.values.bind(yMap) : noBinding('values'), entries: yMap.entries ? yMap.entries.bind(yMap) : noBinding('entries'), forEach: yMap.forEach ? yMap.forEach.bind(yMap) : noBinding('forEach'), delete: yMap.delete ? yMap.delete.bind(yMap) : noBinding('delete'), set: yMap.set ? yMap.set.bind(yMap) : noBinding('set'), get: yMap.get ? yMap.get.bind(yMap) : noBinding('get'), has: yMap.has ? yMap.has.bind(yMap) : noBinding('has'), data: data }; }; var useYMap$1 = useYMap; var useYDoc = function useYDoc(name, mount) { var _useYStore = useYStore$1(function (state) { return [state.mountYDoc, state.unMountYDoc, state.yDocs]; }, shallow__default["default"]), mountYDoc = _useYStore[0], unMountYDoc = _useYStore[1], yDocs = _useYStore[2]; var yDoc = react.useMemo(function () { var match = yDocs.find(function (_ref) { var docGuid = _ref[0]; return docGuid === name; }); if (match) return match[exports.YDocEnum.DOC]; var yDoc = new Y__namespace.Doc(); yDoc.guid = name; mountYDoc(yDoc, mount); return yDoc; }, [yDocs, name]); react.useEffect(function () { return function () { return unMountYDoc(yDoc); }; }, [unMountYDoc, name]); return yDoc; }; var useYDoc$1 = useYDoc; var useYAwareness = function useYAwareness(yDoc) { var matches = useYStore$1(react.useCallback(function (state) { return state.yAwareness.filter(function (_ref) { var guid = _ref[0]; return guid === yDoc.guid; }); }, [yDoc.guid])); var _useMemo = react.useMemo(function () { if (matches.length === 0) return [[], { error: 'Awareness not registered. Use startAwareness method from your YDoc connect function.' }]; var _matches$ = matches[0]; _matches$[0]; var awareness = _matches$[1], changes = _matches$[2]; return [changes, awareness]; }, [matches]), awarenessData = _useMemo[0], awareness = _useMemo[1]; var awarenessSetData = react.useCallback(function (newState) { if (awareness.error) { console.error(awareness.error); } else { var previousState = awareness.getLocalState(); awareness.setLocalState(_extends__default["default"]({}, previousState, newState)); } }, [awareness]); return [awarenessData, awarenessSetData]; }; var useYAwareness$1 = useYAwareness; exports.useYArray = useYArray$1; exports.useYAwareness = useYAwareness$1; exports.useYDoc = useYDoc$1; exports.useYMap = useYMap$1;