diff --git a/package.json b/package.json index 9968c5b..2b2414b 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "express-session": "^1.17.1", "express-socket.io-session": "^1.3.5", "html-entities": "1.3.1", + "immer": "^7.0.1", "memorystore": "^1.6.2", "prop-types": "^15", "react": "16.8.6", diff --git a/src/client/components/traits.jsx b/src/client/components/traits.jsx index 56f59dc..2d4d359 100644 --- a/src/client/components/traits.jsx +++ b/src/client/components/traits.jsx @@ -2,8 +2,9 @@ import {compose, mapObject} from '@avocado/core'; import {all} from '@avocado/entity/trait/trait-components.scwp'; import {lookupTrait} from '@avocado/entity'; import contempo from 'contempo'; +import {produce} from 'immer'; import PropTypes from 'prop-types'; -import React, {useState} from 'react'; +import React, {useEffect, useState} from 'react'; // import ReactMarkdown from 'react-markdown'; import { Tab, @@ -12,7 +13,7 @@ import { TabPanel, } from 'react-tabs'; import {createSelector} from '@reduxjs/toolkit'; -import {invokeHookFlat} from 'scwp'; +import {deregisterHooks, invokeHookFlat, registerHooks} from 'scwp'; const SCROLL_MAG = 80; @@ -80,25 +81,48 @@ const makeTabSelector = (type) => createSelector( }, ); -const tabSelectorMap = new WeakMap(); - const Traits = (props) => { const {traits} = props; - if (!tabSelectorMap.has(traits)) { - tabSelectorMap.set(traits, {}); - } - const selectors = tabSelectorMap.get(traits); + const [tabSelectorMap, setTabSelectorMap] = useState({}); + useEffect(() => { + const entries = Object.entries(traits); + setTabSelectorMap(produce(tabSelectorMap, (draft) => { + for (let i = 0; i < entries.length; i++) { + const [type] = entries[i]; + if (!draft[type]) { + // eslint-disable-next-line no-param-reassign + draft[type] = new WeakMap(); + } + if (!draft[type].has(traits)) { + draft[type].set(traits, makeTabSelector(type)); + } + } + })); + const M = { + autoreg$accept: (type, M2) => { + if ('trait' === type) { + const {default: Trait} = M2; + setTabSelectorMap(produce(tabSelectorMap, (draft) => { + const traitType = Trait.type(); + if (!draft[traitType]) { + // eslint-disable-next-line no-param-reassign + draft[traitType] = new WeakMap(); + } + draft[traitType].set(traits, makeTabSelector(traitType)); + })); + } + }, + }; + registerHooks(M, __filename); + return () => deregisterHooks(M); + }, [tabSelectorMap, traits]); const [tabIndex, setTabIndex] = useState(0); let listRef; const entries = Object.entries(traits); const tabs = []; for (let i = 0; i < entries.length; i++) { const [type, trait] = entries[i]; - trait.type = type; - if (!selectors[type]) { - selectors[type] = makeTabSelector(type); - } - tabs.push([type, selectors[type](trait)]); + tabs.push([type, tabSelectorMap[type]?.get(traits)(trait)]); } return (
@@ -130,10 +154,3 @@ Traits.propTypes = { }; export default decorate(Traits); - -if (module.hot) { - module.hot.accept(['@avocado/entity/trait/trait-components.scwp', () => { - TraitComponents = undefined; - PropertyComponents = undefined; - }]); -} diff --git a/src/client/index.jsx b/src/client/index.jsx index 84946a9..0465dc1 100644 --- a/src/client/index.jsx +++ b/src/client/index.jsx @@ -1,10 +1,13 @@ import './index.scss'; +import {enableMapSet} from 'immer'; import React from 'react'; import {render} from 'react-dom'; import Persea from '~/client/components/persea'; +enableMapSet(); + render( ( diff --git a/yarn.lock b/yarn.lock index 671834c..9f6c8f3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5116,6 +5116,11 @@ immer@^6.0.1: resolved "https://npm.i12e.cha0s.io/immer/-/immer-6.0.9.tgz#b9dd69b8e69b3a12391e87db1e3ff535d1b26485" integrity sha512-SyCYnAuiRf67Lvk0VkwFvwtDoEiCMjeamnHvRfnVDyc7re1/rQrNxuL+jJ7lA3WvdC4uznrvbmm+clJ9+XXatg== +immer@^7.0.1: + version "7.0.1" + resolved "https://npm.i12e.cha0s.io/immer/-/immer-7.0.1.tgz#830f44a36c4181c0eca4385e7782e164e5eb9249" + integrity sha512-DpWL/ES2Ba8KwW+A5AgNRoJPZP8LxdHejKXar1VfbF5a7ATvvekzmmNSQxje+WG0DIhuanvFEumFffVqyCLmBQ== + immutable@4.0.0-rc.12: version "4.0.0-rc.12" resolved "https://npm.i12e.cha0s.io/immutable/-/immutable-4.0.0-rc.12.tgz#ca59a7e4c19ae8d9bf74a97bdf0f6e2f2a5d0217"