feat: hot traits

This commit is contained in:
cha0s 2020-06-17 23:57:25 -05:00
parent 4724070da2
commit 8e5335b497
4 changed files with 46 additions and 20 deletions

View File

@ -34,6 +34,7 @@
"express-session": "^1.17.1", "express-session": "^1.17.1",
"express-socket.io-session": "^1.3.5", "express-socket.io-session": "^1.3.5",
"html-entities": "1.3.1", "html-entities": "1.3.1",
"immer": "^7.0.1",
"memorystore": "^1.6.2", "memorystore": "^1.6.2",
"prop-types": "^15", "prop-types": "^15",
"react": "16.8.6", "react": "16.8.6",

View File

@ -2,8 +2,9 @@ import {compose, mapObject} from '@avocado/core';
import {all} from '@avocado/entity/trait/trait-components.scwp'; import {all} from '@avocado/entity/trait/trait-components.scwp';
import {lookupTrait} from '@avocado/entity'; import {lookupTrait} from '@avocado/entity';
import contempo from 'contempo'; import contempo from 'contempo';
import {produce} from 'immer';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, {useState} from 'react'; import React, {useEffect, useState} from 'react';
// import ReactMarkdown from 'react-markdown'; // import ReactMarkdown from 'react-markdown';
import { import {
Tab, Tab,
@ -12,7 +13,7 @@ import {
TabPanel, TabPanel,
} from 'react-tabs'; } from 'react-tabs';
import {createSelector} from '@reduxjs/toolkit'; import {createSelector} from '@reduxjs/toolkit';
import {invokeHookFlat} from 'scwp'; import {deregisterHooks, invokeHookFlat, registerHooks} from 'scwp';
const SCROLL_MAG = 80; const SCROLL_MAG = 80;
@ -80,25 +81,48 @@ const makeTabSelector = (type) => createSelector(
}, },
); );
const tabSelectorMap = new WeakMap();
const Traits = (props) => { const Traits = (props) => {
const {traits} = props; const {traits} = props;
if (!tabSelectorMap.has(traits)) { const [tabSelectorMap, setTabSelectorMap] = useState({});
tabSelectorMap.set(traits, {}); 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();
} }
const selectors = tabSelectorMap.get(traits); 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); const [tabIndex, setTabIndex] = useState(0);
let listRef; let listRef;
const entries = Object.entries(traits); const entries = Object.entries(traits);
const tabs = []; const tabs = [];
for (let i = 0; i < entries.length; i++) { for (let i = 0; i < entries.length; i++) {
const [type, trait] = entries[i]; const [type, trait] = entries[i];
trait.type = type; tabs.push([type, tabSelectorMap[type]?.get(traits)(trait)]);
if (!selectors[type]) {
selectors[type] = makeTabSelector(type);
}
tabs.push([type, selectors[type](trait)]);
} }
return ( return (
<div className="traits"> <div className="traits">
@ -130,10 +154,3 @@ Traits.propTypes = {
}; };
export default decorate(Traits); export default decorate(Traits);
if (module.hot) {
module.hot.accept(['@avocado/entity/trait/trait-components.scwp', () => {
TraitComponents = undefined;
PropertyComponents = undefined;
}]);
}

View File

@ -1,10 +1,13 @@
import './index.scss'; import './index.scss';
import {enableMapSet} from 'immer';
import React from 'react'; import React from 'react';
import {render} from 'react-dom'; import {render} from 'react-dom';
import Persea from '~/client/components/persea'; import Persea from '~/client/components/persea';
enableMapSet();
render( render(
( (
<Persea /> <Persea />

View File

@ -5116,6 +5116,11 @@ immer@^6.0.1:
resolved "https://npm.i12e.cha0s.io/immer/-/immer-6.0.9.tgz#b9dd69b8e69b3a12391e87db1e3ff535d1b26485" resolved "https://npm.i12e.cha0s.io/immer/-/immer-6.0.9.tgz#b9dd69b8e69b3a12391e87db1e3ff535d1b26485"
integrity sha512-SyCYnAuiRf67Lvk0VkwFvwtDoEiCMjeamnHvRfnVDyc7re1/rQrNxuL+jJ7lA3WvdC4uznrvbmm+clJ9+XXatg== 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: immutable@4.0.0-rc.12:
version "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" resolved "https://npm.i12e.cha0s.io/immutable/-/immutable-4.0.0-rc.12.tgz#ca59a7e4c19ae8d9bf74a97bdf0f6e2f2a5d0217"