From 9eaafc098dfdb242fcd6d94c4b98df40692330c0 Mon Sep 17 00:00:00 2001 From: Peter Czibik
U)a*OD(eYgSi^cdTn}pqcPM(;S)2%1By^Wh%-CaC%>d9hi`7J zaxL7@;nhA>PE%s99&;z{8>VFgf{u!(-B-x7Of6ueme+ScryL`h(^qKE)DtieWY>-7 zgB)VJESQS4*1LU(2&@pgLvSt{(((C?K_V(rQk``i&5}ZPG;G^FiPlZ$7|-vEmMWlU z5lQ%iK2nu=h2wd_7>gK@vX=*AG+u~rQP$NwPC`ZA?4nh{3tui1x@bT6-;Rk3yDQ>d z?3qRD#+PeV7#FAa>s`Xwxsx_oRFcN$StW2=CW`=qObsT?SD^#^jM1Yk}PSPxJ zG@-_mnNU_)vM|iLRSI>UMp|hatyS}17R{10IuL0TLlupt>9dR s_SPQbv7BLYyC#qv16E-y@XZ= z-!p7I%#r-BVi$nQq3&ssRc_IC%R6$tA&^s_l46880~Wst3@>(|EO<}T4~ci~#!=e; zD)B>o%1+$ksURD1p7I-<3ehlFyVkqrySf&gg>Bp
0Z9?JaG|gyTZ{Cb8SdvAWVmFX7v2ohs!OCc!Udk zUITUpmZ33rKLI#(&lDj}c KA#dpL4Fil=$5pu_wi1XJR !llw` zSItPBDEdMHk2>c7#%lBxZ HHvtVUOZ$}v?=?AT~9!Jcqa@IJGuMg(s^7r>pcTrd)pS`{5Cu8WPey` z9)!!OUUY@L%9Q+bZa*S5`3f_|lFCPN6kdp_M2>{le8;cn^XUsPa+TUk47qd6)IBR% zk*&Ip?!Ge_gmmdj)BX}P_5o@VI2*wbZ^>UhFju}0gQZh!pP%4XT9{@w;G#b3XK8sN zF(7i$Jv(IM$8Akys9dhP^^~H2(7BfJp}yDW1#@!CL-!mGcSCnJ599WK9MV@yo_u$v MDeX2GIKR{Qf5okjU;qFB literal 0 HcmV?d00001 diff --git a/examples/using-typescript/public/index.html b/examples/using-typescript/public/index.html new file mode 100644 index 0000000..e0c841e --- /dev/null +++ b/examples/using-typescript/public/index.html @@ -0,0 +1,23 @@ + + + + + + + + + React App + + + + + + diff --git a/examples/using-typescript/public/robots.txt b/examples/using-typescript/public/robots.txt new file mode 100644 index 0000000..e9e57dc --- /dev/null +++ b/examples/using-typescript/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/examples/using-typescript/src/App.tsx b/examples/using-typescript/src/App.tsx new file mode 100644 index 0000000..db8e0d5 --- /dev/null +++ b/examples/using-typescript/src/App.tsx @@ -0,0 +1,33 @@ +import React, { ChangeEvent } from 'react'; +import { view as v, store as s } from 'react-easy-state'; + +const store = s({ + name: 'Peter', + setNameEvent(ev: ChangeEvent) { + if (ev.target) { + this.name = ev.target.value; + } + }, +}); + +// properly retain these props for the views +type AppProps = { + greeting: string; +}; + +const App: React.FC = v(({ greeting, children }) => ( + ++)); + +export default App; diff --git a/examples/using-typescript/src/index.css b/examples/using-typescript/src/index.css new file mode 100644 index 0000000..ec2585e --- /dev/null +++ b/examples/using-typescript/src/index.css @@ -0,0 +1,13 @@ +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + monospace; +} diff --git a/examples/using-typescript/src/index.tsx b/examples/using-typescript/src/index.tsx new file mode 100644 index 0000000..850f212 --- /dev/null +++ b/examples/using-typescript/src/index.tsx @@ -0,0 +1,11 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import './index.css'; +import App from './App'; + +const ref = React.createRef+ {greeting} {store.name}! +
+ + + {children} +(); + +ReactDOM.render( + , + document.getElementById('root'), +); diff --git a/examples/using-typescript/src/react-app-env.d.ts b/examples/using-typescript/src/react-app-env.d.ts new file mode 100644 index 0000000..6431bc5 --- /dev/null +++ b/examples/using-typescript/src/react-app-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/examples/using-typescript/src/setupTests.ts b/examples/using-typescript/src/setupTests.ts new file mode 100644 index 0000000..74b1a27 --- /dev/null +++ b/examples/using-typescript/src/setupTests.ts @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom/extend-expect'; diff --git a/examples/using-typescript/tsconfig.json b/examples/using-typescript/tsconfig.json new file mode 100644 index 0000000..af10394 --- /dev/null +++ b/examples/using-typescript/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react" + }, + "include": ["src"] +} diff --git a/jest.ts.js b/jest.ts.js new file mode 100644 index 0000000..8402f6a --- /dev/null +++ b/jest.ts.js @@ -0,0 +1,29 @@ +module.exports = { + globals: { + 'ts-jest': { + babelConfig: 'babel.config.js', + tsConfig: './examples/using-typescript/tsconfig.json', + }, + }, + setupFilesAfterEnv: ['./scripts/testSetup.js'], + testURL: 'http://react-easy-state.com', + testRegex: '\\.test\\.tsx?$', + collectCoverage: true, + preset: 'ts-jest', + testEnvironment: 'jsdom', + coverageReporters: ['text'], + transform: { + '^.+\\.jsx?$': 'babel-jest', // Adding this line solved the issue + '^.+\\.tsx?$': 'ts-jest', + }, + collectCoverageFrom: [ + 'src/**/*.{ts,tsx}', + 'examples/**/*.{ts,tsx}', + '!examples/**/build/**', + '!examples/**/index.js', + '!examples/stop-watch/**', + '!examples/beer-finder/**', + '!examples/native-clock/**', + ], + coverageDirectory: 'coverage', +}; diff --git a/package-lock.json b/package-lock.json index ff20929..936083a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5667,9 +5667,9 @@ } }, "@types/jest": { - "version": "25.1.1", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.1.1.tgz", - "integrity": "sha512-bKSZJYZJLzwaoVYNN4W3A0RvKNYsrLm5tsuXaMlfYDxKf4gY2sFrMYneCugNQWGg1gjPW+FHBwNrwPzEi4sIsw==", + "version": "25.1.4", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.1.4.tgz", + "integrity": "sha512-QDDY2uNAhCV7TMCITrxz+MRk1EizcsevzfeS6LykIlq2V1E5oO4wXG8V2ZEd9w7Snxeeagk46YbMgZ8ESHx3sw==", "dev": true, "requires": { "jest-diff": "^25.1.0", @@ -5689,9 +5689,9 @@ } }, "@types/yargs": { - "version": "15.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.3.tgz", - "integrity": "sha512-XCMQRK6kfpNBixHLyHUsGmXrpEmFFxzMrcnSXFMziHd8CoNJo8l16FkHyQq4x+xbM7E2XL83/O78OD8u+iZTdQ==", + "version": "15.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.4.tgz", + "integrity": "sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg==", "dev": true, "requires": { "@types/yargs-parser": "*" @@ -5757,9 +5757,9 @@ } }, "react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", + "version": "16.13.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.0.tgz", + "integrity": "sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA==", "dev": true }, "supports-color": { @@ -7031,6 +7031,15 @@ "node-releases": "^1.1.47" } }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, "bser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", @@ -15311,6 +15320,12 @@ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", @@ -15461,6 +15476,12 @@ } } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "makeerror": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", @@ -20364,6 +20385,36 @@ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, + "ts-jest": { + "version": "25.2.1", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-25.2.1.tgz", + "integrity": "sha512-TnntkEEjuXq/Gxpw7xToarmHbAafgCaAzOpnajnFC6jI7oo1trMzAHA04eWpc3MhV6+yvhE8uUBAmN+teRJh0A==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "buffer-from": "1.x", + "fast-json-stable-stringify": "2.x", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "mkdirp": "0.x", + "resolve": "1.x", + "semver": "^5.5", + "yargs-parser": "^16.1.0" + }, + "dependencies": { + "yargs-parser": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-16.1.0.tgz", + "integrity": "sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", @@ -20421,6 +20472,12 @@ "is-typedarray": "^1.0.0" } }, + "typescript": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz", + "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==", + "dev": true + }, "ua-parser-js": { "version": "0.7.19", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.19.tgz", diff --git a/package.json b/package.json index 995fd3f..b03a424 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "scripts": { "test-native": "NATIVE=true jest --config ./jest.native.json --silent", "test-web": "jest --config ./jest.web.json --silent", + "test-ts": "jest --config ./jest.ts.js --silent", "test-web-no-hook": "NOHOOK=true jest --config ./jest.no-hook.json --silent", "test": "npm run test-web && npm run test-web-no-hook && npm run test-native", "example": "node ./scripts/startExample.js", @@ -75,6 +76,7 @@ "@rollup/plugin-node-resolve": "^7.1.1", "@testing-library/jest-dom": "^5.1.1", "@testing-library/react": "^9.4.0", + "@types/jest": "25.1.4", "@types/react": "^16.9.19", "babel-eslint": "^10.0.3", "classnames": "^2.2.6", @@ -91,10 +93,10 @@ "jest": "^25.1.0", "markdown-toc": "^1.2.0", "moment": "^2.24.0", - "nyc": "^15.0.0", "no-hook-react": "npm:react@16.7.0", "no-hook-react-dom": "npm:react-dom@16.7.0", "no-hook-react-testing-library": "npm:react-testing-library@5.4.4", + "nyc": "^15.0.0", "prettier": "^1.19.1", "react": "^16.12.0", "react-dom": "^16.12.0", @@ -106,7 +108,9 @@ "rollup-plugin-auto-external": "^2.0.0", "rollup-plugin-babel": "^4.3.3", "sinon": "^8.1.1", - "styled-components": "^5.0.1" + "styled-components": "^5.0.1", + "ts-jest": "25.2.1", + "typescript": "3.8.3" }, "engines": { "node": ">=10.0.0", diff --git a/types/index.d.ts b/types/index.d.ts index e662008..9681f5c 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -4,7 +4,7 @@ declare module 'react-easy-state' { // takes an object (optionally), wraps it in a transparent proxy and returns the proxy function store (obj?: Store): Store; // takes class or function component and returns a class HOC - function view >(comp: Comp): Comp; + function view >(comp: T): T; // this runs the passed function and delays all re-renders until the function is finished running function batch ( fn: (...args: any[]) => T,