diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..1ff94f7 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["next/babel"] +} diff --git a/components/opt-toy/AOPActivationTable.tsx b/components/opt-toy/AOPActivationTable.tsx index f0efd96..54e5e99 100644 --- a/components/opt-toy/AOPActivationTable.tsx +++ b/components/opt-toy/AOPActivationTable.tsx @@ -1,12 +1,26 @@ import * as React from "react" -import { OPT512 } from "./OPT512" -import { betweenX } from "./between" +import { + Blast, + Consume, + Feeling, + iNtuition, + OPT512, + Play, + Sensing, + Sleep, + Thinking, +} from "./OPT512" +import { FC } from "react" +import { isSSR } from "../../util/constants" export default function AOPActivationTable({ op512 }: { op512: OPT512 }) { + if (isSSR) { + return null + } const showSex = op512.fmDe !== "?" || op512.fmS !== "?" return (
- + + +
+ + Open in previous version of opt-toy + +
+
+ ) +} + export default function OptToyApp() { - const { - setOPTypeTextAtIndex, - typeIDs, - typeIDInsertBefore, - types, - addType, - } = useStuff() + const { setOPTypeTextAtIndex, typeIDs, typeIDInsertBefore, types, addType } = + useStuff() const [showKnowns, setShowKnown] = useQueryDataKey("showKnown", []) const showKnown = showKnowns.length > 0 const [showSettings, setShowSettings] = useState(false) @@ -246,18 +289,10 @@ export default function OptToyApp() {
{showSettings && ( -
- -
+ )}
@@ -265,27 +300,28 @@ export default function OptToyApp() { {showKnown && } -
- {types.map((defaultType, index) => ( - void setOPTypeTextAtIndex(index, null), - onChangeText: (opTypeText: any) => - void setOPTypeTextAtIndex(index, opTypeText), - selected: types.length === 1, - defaultType, - showOPTable, - }} - /> - ))} -
- + {!isSSR && ( +
+ {types.map((defaultType, index) => ( + void setOPTypeTextAtIndex(index, null), + onChangeText: (opTypeText: any) => + void setOPTypeTextAtIndex(index, opTypeText), + selected: types.length === 1, + defaultType, + showOPTable, + }} + /> + ))} +
+ )} ) diff --git a/components/opt-toy/TypeThing.tsx b/components/opt-toy/TypeThing.tsx index e90024f..29719b2 100644 --- a/components/opt-toy/TypeThing.tsx +++ b/components/opt-toy/TypeThing.tsx @@ -1,20 +1,20 @@ -import React, { FC, useEffect, useState, createContext } from "react" +import React, { FC, useEffect, useState, createContext, useMemo } from "react" import useUndo from "use-undo" import { AOPActivationSpectrums } from "./AOPActivationSpectrums" import AOPActivationTable from "./AOPActivationTable" import { betweenX } from "./between" -import { BLANK_TYPE, cleanCoinText, OPT512Maybe, parseCoinText } from "./Coin" +import { BLANK_TYPE, OPT512Maybe, parseCoinText } from "./Coin" import OPActivationTable from "./OPActivationTable" import { OPCodeInput } from "./OPCodeInput" import { OPTGraph } from "./opt128-svgr" -import { OPT512 } from "./OPT512" +import { cleanCoinText, OPT512 } from "./OPT512" import { OPTypeBinaryForm } from "./OPTypeBinaryForm" const isSSR = typeof window === "undefined" function OPTypeBinaryText({ type }: { type: OPT512Maybe }) { const opt = new OPT512(type) - return {opt.OP512} + return {opt.OPSCode} } const SEPARATOR = `!` @@ -38,7 +38,7 @@ const History = (props) => ( redo ) @@ -68,39 +68,44 @@ export type TypeThingProps = { HTMLDivElement > +type NameAndTypeText = { + name: string + typeText: string +} + export const TypeThing: FC = ({ selected = false, - defaultType, + defaultType: defaultTypeAndName, onClose = null, onChangeText = null, showOPTable = true, ...props }) => { - useEffect(() => { - opTypeActions.reset({ - name: String(defaultType.split(SEPARATOR)[1] || ""), - type: parseCoinText(cleanCoinText(defaultType.split(SEPARATOR)[0])), - }) - }, []) + const defaultState = useMemo( + () => ({ + name: String(defaultTypeAndName.split(SEPARATOR)[1] || ""), + typeText: defaultTypeAndName + ? cleanCoinText(defaultTypeAndName.split(SEPARATOR)[0]) + : "", + }), + [defaultTypeAndName], + ) + const [name, setName] = useState(defaultState.name) + const [type, setType] = useState( + () => OPT512.from(defaultState.typeText).type, + ) + const opTypeInstance = new OPT512(type) + const typeText = opTypeInstance.OPSCode - const [isOpen, setIsOpen] = useState(selected) - const [opType, opTypeActions] = useUndo({ - name: "loading...", - type: BLANK_TYPE, - }) - const opTypeInstance = new OPT512(opType.present.type) - const typeText = opTypeInstance.OP512 + useEffect(() => { + console.log(opTypeInstance) + }, [typeText, ...type]) useEffect(() => { - if (opType.past.length === 0) return - if (onChangeText) { - onChangeText( - `${typeText}${ - opType.present.name ? SEPARATOR + opType.present.name : "" - }`, - ) - } - }, [opType.present.name, typeText]) + onChangeText?.(`${typeText}${name ? SEPARATOR + name : ""}`) + }, [name, typeText]) + + const [isOpen, setIsOpen] = useState(selected) const placeholderName = `${opTypeInstance.S1}/${opTypeInstance.S2}` return ( @@ -164,19 +169,12 @@ export const TypeThing: FC = ({ e.stopPropagation()} - onChange={(e) => - opTypeActions.set({ - type: opType.present.type, - name: e.currentTarget.value, - }) - } - value={opType.present.name} + onChange={({ currentTarget: { value: name } }) => setName(name)} + value={name} placeholder={placeholderName} /> ) : ( -
- {opType.present.name || placeholderName} -
+
{name || placeholderName}
)} @@ -189,14 +187,12 @@ export const TypeThing: FC = ({ e.stopPropagation()} - coins={opTypeInstance.type} - onParsed={(type) => { - opTypeActions.set({ name: opType.present.name, type }) - }} + opType={opTypeInstance} + onChange={(opType) => setType(opType.type)} /> ) : (
- +
)} @@ -207,7 +203,9 @@ export const TypeThing: FC = ({ )} - {opTypeInstance.isFull && } + {opTypeInstance.isFull && ( + + )}
{isOpen && ( @@ -222,8 +220,8 @@ export const TypeThing: FC = ({ }} > - - + {/* */} + {/* */} {onClose && ( )} - { - opTypeActions.set({ name: opType.present.name, type }) - }} - /> + )}{" "} diff --git a/components/opt-toy/euclideanDistance.ts b/components/opt-toy/euclideanDistance.ts index f5044c9..fdbfcd0 100644 --- a/components/opt-toy/euclideanDistance.ts +++ b/components/opt-toy/euclideanDistance.ts @@ -1,4 +1,5 @@ export const euclideanDistance = (aaa: number[], bbb: number[]) => { + if (!(aaa && bbb)) return NaN; return Math.sqrt(euclideanDistanceSquared(aaa, bbb)) } diff --git a/components/opt-toy/opt128-svgr.tsx b/components/opt-toy/opt128-svgr.tsx index 651f698..d5d67cf 100644 --- a/components/opt-toy/opt128-svgr.tsx +++ b/components/opt-toy/opt128-svgr.tsx @@ -4,12 +4,16 @@ import { SVG_OP_Bubble, SVG_OP_Bubble_border } from "./SVG_OP_Bubble" import { bubbleTextStyle } from "./SVG_OP_BubbleText" import { OPFunctionType, OPT512 } from "./OPT512" import { download } from "../../util/download" -import { renderToStaticMarkup } from 'react-dom/server' +import { renderToStaticMarkup } from "react-dom/server" +import { isSSR } from "../../util/constants" export const OPTGraph = forwardRef< SVGSVGElement, { opType: OPT512 } & React.SVGProps >(({ opType, ...props }, svgRef0) => { + if (isSSR) { + return null + } const svgRef = useRef() const { opFunctions } = opType const opAnimals = { @@ -39,7 +43,10 @@ export const OPTGraph = forwardRef< onContextMenu={(e) => { download( opType.toString().replace(/[-/()]/g, "") + ".svg", - svgRef.current.outerHTML.replace(``,`${renderToStaticMarkup()}`), + svgRef.current.outerHTML.replace( + ``, + `${renderToStaticMarkup()}`, + ), ) }} > diff --git a/components/opt-toy/sortBy.tsx b/components/opt-toy/sortBy.tsx index d2cef93..4f9d1ea 100644 --- a/components/opt-toy/sortBy.tsx +++ b/components/opt-toy/sortBy.tsx @@ -2,7 +2,8 @@ export const sortBy = (a: string | number, b: string | number) => a > b ? 1 : b > a ? -1 : 0 export const sorterize = ( - getSortValue: (thing: T) => number | string, -) => (a: T, b: T) => sortBy(getSortValue(a), getSortValue(b)) + getSortValue: (thing: T) => any, + _sortBy: typeof sortBy = sortBy +) => (a: T, b: T) => _sortBy(getSortValue(a), getSortValue(b)) export const sortByRandom = sorterize(Math.random) diff --git a/config/jest/cssTransform.js b/config/jest/cssTransform.js new file mode 100644 index 0000000..a99f754 --- /dev/null +++ b/config/jest/cssTransform.js @@ -0,0 +1,9 @@ +// https://jestjs.io/docs/code-transformation#writing-custom-transformers +module.exports = { + process() { + return "module.exports = {};" + }, + getCacheKey() { + return "cssTransform" + }, +} diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..a2a6ff1 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,21 @@ +/** @type {import('@jest/types').Config.InitialOptions} */ +module.exports = { + collectCoverageFrom: [ + "**/*.{js,jsx,ts,tsx}", + "!**/*.d.ts", + "!**/node_modules/**", + ], + setupFilesAfterEnv: ["/setupTests.js"], + testPathIgnorePatterns: ["/node_modules/", "/.next/"], + transform: { + "^.+\\.(js|jsx|ts|tsx)$": "babel-jest", + "^.+\\.css$": "/config/jest/cssTransform.js", + }, + transformIgnorePatterns: [ + "/node_modules/", + "^.+\\.module\\.(css|sass|scss)$", + ], + moduleNameMapper: { + "^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy", + }, +} diff --git a/next-env.d.ts b/next-env.d.ts index 7b7aa2c..c6643fd 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -1,2 +1,3 @@ /// /// +/// diff --git a/package.json b/package.json index fce2db0..6fcb186 100644 --- a/package.json +++ b/package.json @@ -1,27 +1,39 @@ { "name": "@opdex/toy", - "version": "10.0.0", + "version": "11.0.0", "private": true, "prettier": { "trailingComma": "all", - "semi": false + "semi": false, + "printWidth": 80 }, "main": "./components/opt-toy/index.tsx", "scripts": { "dev": "next dev", "build": "next build", - "start": "next start" + "start": "next start", + "test": "jest --watch", + "test:ci": "jest --ci" }, "dependencies": { - "next": "10.0.5", - "react": "17.0.1", - "react-dom": "17.0.1", + "next": "11.0.1", + "react": "17.0.2", + "react-dom": "17.0.2", "use-undo": "^1.0.3" }, "devDependencies": { - "@types/node": "^14.14.21", + "@babel/core": "^7.14.8", + "@babel/preset-env": "^7.14.8", + "@babel/preset-typescript": "^7.14.5", + "@testing-library/jest-dom": "^5.14.1", + "@testing-library/react": "^12.0.0", + "@types/node": "^16.4.12", "@types/react": "^17.0.0", "@types/react-dom": "^17.0.0", + "babel-jest": "^27.0.6", + "identity-obj-proxy": "^3.0.0", + "jest": "^27.0.6", + "react-test-renderer": "^17.0.2", "typescript": "^4.1.3" } } diff --git a/setupTests.js b/setupTests.js new file mode 100644 index 0000000..9b5f04e --- /dev/null +++ b/setupTests.js @@ -0,0 +1,6 @@ +// optional: configure or set up a testing framework before each test +// if you delete this file, remove `setupFilesAfterEnv` from `jest.config.js` + +// used for __tests__/testing-library.js +// learn more: https://github.com/testing-library/jest-dom +import "@testing-library/jest-dom/extend-expect" diff --git a/util/constants.ts b/util/constants.ts new file mode 100644 index 0000000..0319a77 --- /dev/null +++ b/util/constants.ts @@ -0,0 +1 @@ +export const isSSR = typeof window === "undefined"