├── phaseA ├── tests │ ├── _setup.ts │ └── index.ts ├── .npmrc ├── .prettierrc ├── src │ ├── index.ts │ ├── @types │ │ └── reactAst.d.ts │ ├── elements │ │ ├── index.ts │ │ └── BaseElement.ts │ ├── render.ts │ └── types.ts ├── .babelrc ├── .editorconfig ├── example │ ├── index.tsx │ └── tsconfig.json ├── tsconfig.json ├── README.md ├── .eslintrc ├── LICENSE └── .gitignore ├── phaseB ├── tests │ ├── _setup.ts │ └── index.ts ├── .npmrc ├── .prettierrc ├── src │ ├── index.ts │ ├── elements │ │ ├── Hello.ts │ │ ├── Howdy.ts │ │ ├── Wrapper.ts │ │ ├── index.ts │ │ └── BaseElement.ts │ ├── createElement.ts │ ├── @types │ │ └── reactAst.d.ts │ ├── render.ts │ └── types.ts ├── .babelrc ├── .editorconfig ├── example │ ├── index.tsx │ └── tsconfig.json ├── tsconfig.json ├── .eslintrc ├── README.md ├── LICENSE └── .gitignore ├── phaseC ├── tests │ ├── _setup.ts │ └── index.ts ├── .npmrc ├── .prettierrc ├── src │ ├── index.ts │ ├── elements │ │ ├── Hello.ts │ │ ├── Howdy.ts │ │ ├── index.ts │ │ ├── Wrapper.ts │ │ └── BaseElement.ts │ ├── createElement.ts │ ├── @types │ │ └── reactAst.d.ts │ ├── render.ts │ └── types.ts ├── .babelrc ├── .editorconfig ├── example │ ├── index.tsx │ └── tsconfig.json ├── tsconfig.json ├── README.md ├── .eslintrc ├── LICENSE └── .gitignore ├── phaseD ├── tests │ ├── _setup.ts │ └── index.ts ├── .npmrc ├── .prettierrc ├── src │ ├── index.ts │ ├── elements │ │ ├── index.ts │ │ ├── File.ts │ │ └── BaseElement.ts │ ├── @types │ │ └── reactAst.d.ts │ ├── createElement.ts │ └── render.ts ├── .babelrc ├── .editorconfig ├── example │ ├── index.tsx │ └── tsconfig.json ├── tsconfig.json ├── README.md ├── .eslintrc ├── LICENSE └── .gitignore ├── phaseE ├── tests │ ├── _setup.ts │ └── index.ts ├── .npmrc ├── .prettierrc ├── src │ ├── index.ts │ ├── elements │ │ ├── index.ts │ │ └── File.ts │ ├── @types │ │ └── reactAst.d.ts │ ├── createElement.ts │ ├── util.ts │ └── render.ts ├── .babelrc ├── .editorconfig ├── example │ ├── index.tsx │ └── tsconfig.json ├── tsconfig.json ├── README.md ├── .eslintrc ├── LICENSE └── .gitignore ├── phaseF ├── tests │ ├── _setup.ts │ └── index.ts ├── .npmrc ├── .prettierrc ├── src │ ├── index.ts │ ├── elements │ │ ├── index.ts │ │ └── File.ts │ ├── @types │ │ └── reactAst.d.ts │ ├── createElement.ts │ ├── util.ts │ └── render.ts ├── .babelrc ├── .editorconfig ├── example │ ├── index.tsx │ └── tsconfig.json ├── tsconfig.json ├── .eslintrc ├── LICENSE ├── README.md └── .gitignore ├── phaseG ├── tests │ ├── _setup.ts │ └── index.ts ├── .npmrc ├── .prettierrc ├── src │ ├── index.ts │ ├── createElement.ts │ ├── elements │ │ ├── Program.ts │ │ ├── File.ts │ │ ├── index.ts │ │ ├── Expression.ts │ │ └── Ast.ts │ ├── util.ts │ ├── render.ts │ └── @types │ │ └── reactAst.d.ts ├── .babelrc ├── .editorconfig ├── example │ ├── index.tsx │ └── tsconfig.json ├── README.md ├── tsconfig.json ├── .eslintrc └── LICENSE ├── phaseH ├── tests │ ├── _setup.ts │ └── index.ts ├── .npmrc ├── .prettierrc ├── src │ ├── index.ts │ ├── createElement.ts │ ├── elements │ │ ├── Program.ts │ │ ├── File.ts │ │ ├── index.ts │ │ ├── Expression.ts │ │ └── Ast.ts │ ├── util.ts │ ├── render.ts │ └── @types │ │ └── reactAst.d.ts ├── .babelrc ├── .editorconfig ├── example │ ├── index.tsx │ └── tsconfig.json ├── tsconfig.json ├── .eslintrc └── LICENSE ├── phaseI ├── tests │ ├── _setup.ts │ └── index.ts ├── .npmrc ├── .prettierrc ├── src │ ├── index.ts │ ├── createElement.ts │ ├── elements │ │ ├── Program.ts │ │ ├── File.ts │ │ ├── index.ts │ │ ├── Expression.ts │ │ └── Ast.ts │ ├── util.ts │ ├── dev.ts │ ├── render.ts │ └── @types │ │ └── reactAst.d.ts ├── .babelrc ├── .editorconfig ├── example │ ├── index.tsx │ └── tsconfig.json ├── tsconfig.json ├── .eslintrc └── LICENSE ├── phaseJ ├── tests │ ├── _setup.ts │ └── index.ts ├── .npmrc ├── .prettierrc ├── src │ ├── index.ts │ ├── createElement.ts │ ├── elements │ │ ├── Program.ts │ │ ├── File.ts │ │ ├── index.ts │ │ ├── Expression.ts │ │ └── Ast.ts │ ├── util.ts │ ├── dev.ts │ ├── render.ts │ └── @types │ │ └── reactAst.d.ts ├── .babelrc ├── .editorconfig ├── tsconfig.json ├── example │ ├── tsconfig.json │ └── index.tsx ├── README.md ├── .eslintrc └── LICENSE ├── phaseK ├── tests │ ├── _setup.ts │ └── index.ts ├── .npmrc ├── .prettierrc ├── src │ ├── index.ts │ ├── elements │ │ ├── Program.ts │ │ ├── File.ts │ │ ├── index.ts │ │ ├── Expression.ts │ │ └── Ast.ts │ ├── util.ts │ ├── dev.ts │ ├── createElement.ts │ ├── context.ts │ └── @types │ │ └── reactAst.d.ts ├── .babelrc ├── .editorconfig ├── example │ ├── index.tsx │ └── tsconfig.json ├── tsconfig.json ├── README.md ├── .eslintrc └── LICENSE ├── phaseL ├── tests │ ├── _setup.ts │ └── index.ts ├── .npmrc ├── .prettierrc ├── src │ ├── components │ │ ├── Code │ │ │ ├── index.ts │ │ │ ├── Code.tsx │ │ │ └── Code.spec.tsx │ │ ├── Param │ │ │ ├── index.ts │ │ │ ├── Param.spec.tsx │ │ │ └── Param.tsx │ │ ├── Literal │ │ │ ├── index.ts │ │ │ ├── Literal.tsx │ │ │ └── Literal.spec.tsx │ │ ├── TypeParam │ │ │ ├── index.ts │ │ │ └── TypeParam.tsx │ │ ├── ClassMethod │ │ │ └── index.ts │ │ ├── JsxElement │ │ │ └── index.ts │ │ ├── CallExpression │ │ │ ├── index.ts │ │ │ ├── CallExpression.spec.tsx │ │ │ └── CallExpression.tsx │ │ ├── ClassProperty │ │ │ ├── index.ts │ │ │ ├── ClassProperty.spec.tsx │ │ │ └── ClassProperty.tsx │ │ ├── JsxAttribute │ │ │ ├── index.ts │ │ │ ├── JsxAttribute.spec.tsx │ │ │ └── JsxAttribute.tsx │ │ ├── TypeAnnotation │ │ │ ├── index.ts │ │ │ └── TypeAnnotation.tsx │ │ ├── ClassDeclaration │ │ │ ├── index.ts │ │ │ ├── ClassDeclaration.spec.tsx │ │ │ └── ClassDeclaration.tsx │ │ ├── MethodSignature │ │ │ ├── index.ts │ │ │ └── MethodSignature.spec.tsx │ │ ├── ReturnStatement │ │ │ ├── index.ts │ │ │ ├── ReturnStatement.spec.tsx │ │ │ └── ReturnStatement.tsx │ │ ├── FunctionDeclaration │ │ │ ├── index.ts │ │ │ └── FunctionDeclaration.spec.tsx │ │ ├── FunctionExpression │ │ │ ├── index.ts │ │ │ └── FunctionExpression.spec.tsx │ │ ├── ImportDeclaration │ │ │ ├── index.ts │ │ │ ├── ImportDeclaration.spec.tsx │ │ │ └── ImportDeclaration.tsx │ │ ├── PropertySignature │ │ │ ├── index.ts │ │ │ ├── PropertySignature.tsx │ │ │ └── PropertySignature.spec.tsx │ │ ├── VariableDeclaration │ │ │ ├── index.ts │ │ │ └── VariableDeclaration.spec.tsx │ │ ├── InterfaceDeclaration │ │ │ ├── index.ts │ │ │ ├── InterfaceDeclaration.tsx │ │ │ └── InterfaceDeclaration.spec.tsx │ │ ├── ArrowFunctionExpression │ │ │ ├── index.ts │ │ │ └── ArrowFunctionExpression.spec.tsx │ │ ├── ExportDefaultDeclaration │ │ │ ├── index.ts │ │ │ ├── ExportDefaultDeclaration.tsx │ │ │ └── ExportDefaultDeclaration.spec.tsx │ │ ├── ExportNamedDeclaration │ │ │ ├── index.ts │ │ │ ├── ExportNamedDeclaration.tsx │ │ │ └── ExportNamedDeclaration.spec.tsx │ │ └── index.ts │ ├── index.ts │ ├── elements │ │ ├── Program.ts │ │ ├── File.ts │ │ ├── index.ts │ │ ├── Expression.ts │ │ └── Ast.ts │ ├── util.ts │ ├── dev.ts │ ├── createElement.ts │ ├── context.ts │ └── @types │ │ └── reactAst.d.ts ├── .babelrc ├── .editorconfig ├── example │ ├── Body.tsx │ ├── tsconfig.json │ ├── ReactClassComponent.tsx │ ├── index.tsx │ └── ReactFunctionalComponent.tsx ├── README.md ├── tsconfig.json ├── .eslintrc └── LICENSE ├── slides ├── .eslintignore ├── .prettierrc ├── .gitignore ├── assets │ ├── react.png │ ├── good-work.gif │ ├── baning-head-on-wall.gif │ ├── react-renderer-binding-diagram.jpg │ ├── deck.example │ └── interactive.js ├── .eslintrc ├── presentation │ └── slides │ │ ├── Spoiler.js │ │ ├── Phase.js │ │ ├── Home.js │ │ ├── Definition.js │ │ ├── Tips.js │ │ ├── Diagram.js │ │ └── Introduction.js ├── .babelrc ├── server.js ├── index.html ├── index.js └── LICENSE ├── .gitignore ├── lerna.json ├── assets └── create-react-renderer.png ├── react-renderer-binding-diagram.epgz └── package.json /phaseA/tests/_setup.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /phaseB/tests/_setup.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /phaseC/tests/_setup.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /phaseD/tests/_setup.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /phaseE/tests/_setup.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /phaseF/tests/_setup.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /phaseG/tests/_setup.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /phaseH/tests/_setup.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /phaseI/tests/_setup.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /phaseJ/tests/_setup.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /phaseK/tests/_setup.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /phaseL/tests/_setup.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /slides/.eslintignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | -------------------------------------------------------------------------------- /phaseA/.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /phaseB/.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /phaseC/.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /phaseD/.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /phaseE/.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /phaseF/.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /phaseG/.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /phaseH/.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /phaseI/.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /phaseJ/.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /phaseK/.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /phaseL/.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /phaseA/.prettierrc: -------------------------------------------------------------------------------- 1 | singleQuote: true 2 | -------------------------------------------------------------------------------- /phaseB/.prettierrc: -------------------------------------------------------------------------------- 1 | singleQuote: true 2 | -------------------------------------------------------------------------------- /phaseC/.prettierrc: -------------------------------------------------------------------------------- 1 | singleQuote: true 2 | -------------------------------------------------------------------------------- /phaseD/.prettierrc: -------------------------------------------------------------------------------- 1 | singleQuote: true 2 | -------------------------------------------------------------------------------- /phaseE/.prettierrc: -------------------------------------------------------------------------------- 1 | singleQuote: true 2 | -------------------------------------------------------------------------------- /phaseF/.prettierrc: -------------------------------------------------------------------------------- 1 | singleQuote: true 2 | -------------------------------------------------------------------------------- /phaseG/.prettierrc: -------------------------------------------------------------------------------- 1 | singleQuote: true 2 | -------------------------------------------------------------------------------- /phaseH/.prettierrc: -------------------------------------------------------------------------------- 1 | singleQuote: true 2 | -------------------------------------------------------------------------------- /phaseI/.prettierrc: -------------------------------------------------------------------------------- 1 | singleQuote: true 2 | -------------------------------------------------------------------------------- /phaseJ/.prettierrc: -------------------------------------------------------------------------------- 1 | singleQuote: true 2 | -------------------------------------------------------------------------------- /phaseK/.prettierrc: -------------------------------------------------------------------------------- 1 | singleQuote: true 2 | -------------------------------------------------------------------------------- /phaseL/.prettierrc: -------------------------------------------------------------------------------- 1 | singleQuote: true 2 | -------------------------------------------------------------------------------- /slides/.prettierrc: -------------------------------------------------------------------------------- 1 | singleQuote: true 2 | -------------------------------------------------------------------------------- /phaseL/src/components/Code/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Code'; 2 | -------------------------------------------------------------------------------- /phaseL/src/components/Param/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Param'; 2 | -------------------------------------------------------------------------------- /phaseL/src/components/Literal/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Literal'; 2 | -------------------------------------------------------------------------------- /phaseL/src/components/TypeParam/index.ts: -------------------------------------------------------------------------------- 1 | export * from './TypeParam'; 2 | -------------------------------------------------------------------------------- /phaseA/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './render'; 2 | export * from './types'; 3 | -------------------------------------------------------------------------------- /phaseL/src/components/ClassMethod/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ClassMethod'; 2 | -------------------------------------------------------------------------------- /phaseL/src/components/JsxElement/index.ts: -------------------------------------------------------------------------------- 1 | export * from './JsxElement'; 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | package-lock.json 2 | yarn.lock 3 | node_modules 4 | slides/core 5 | -------------------------------------------------------------------------------- /phaseL/src/components/CallExpression/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CallExpression'; 2 | -------------------------------------------------------------------------------- /phaseL/src/components/ClassProperty/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ClassProperty'; 2 | -------------------------------------------------------------------------------- /phaseL/src/components/JsxAttribute/index.ts: -------------------------------------------------------------------------------- 1 | export * from './JsxAttribute'; 2 | -------------------------------------------------------------------------------- /phaseL/src/components/TypeAnnotation/index.ts: -------------------------------------------------------------------------------- 1 | export * from './TypeAnnotation'; 2 | -------------------------------------------------------------------------------- /phaseL/src/components/ClassDeclaration/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ClassDeclaration'; 2 | -------------------------------------------------------------------------------- /phaseL/src/components/MethodSignature/index.ts: -------------------------------------------------------------------------------- 1 | export * from './MethodSignature'; 2 | -------------------------------------------------------------------------------- /phaseL/src/components/ReturnStatement/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ReturnStatement'; 2 | -------------------------------------------------------------------------------- /phaseL/src/components/FunctionDeclaration/index.ts: -------------------------------------------------------------------------------- 1 | export * from './FunctionDeclaration'; 2 | -------------------------------------------------------------------------------- /phaseL/src/components/FunctionExpression/index.ts: -------------------------------------------------------------------------------- 1 | export * from './FunctionExpression'; 2 | -------------------------------------------------------------------------------- /phaseL/src/components/ImportDeclaration/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ImportDeclaration'; 2 | -------------------------------------------------------------------------------- /phaseL/src/components/PropertySignature/index.ts: -------------------------------------------------------------------------------- 1 | export * from './PropertySignature'; 2 | -------------------------------------------------------------------------------- /phaseL/src/components/VariableDeclaration/index.ts: -------------------------------------------------------------------------------- 1 | export * from './VariableDeclaration'; 2 | -------------------------------------------------------------------------------- /slides/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | npm-debug.log 4 | dist 5 | yarn.lock 6 | -------------------------------------------------------------------------------- /phaseL/src/components/InterfaceDeclaration/index.ts: -------------------------------------------------------------------------------- 1 | export * from './InterfaceDeclaration'; 2 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "npmClient": "yarn", 3 | "packages": ["*"], 4 | "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /phaseA/src/@types/reactAst.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace JSX { 2 | interface IntrinsicElements {} 3 | } 4 | -------------------------------------------------------------------------------- /phaseL/src/components/ArrowFunctionExpression/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ArrowFunctionExpression'; 2 | -------------------------------------------------------------------------------- /phaseL/src/components/ExportDefaultDeclaration/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ExportDefaultDeclaration'; 2 | -------------------------------------------------------------------------------- /phaseL/src/components/ExportNamedDeclaration/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ExportNamedDeclaration'; 2 | -------------------------------------------------------------------------------- /phaseA/src/elements/index.ts: -------------------------------------------------------------------------------- 1 | import BaseElement from './BaseElement'; 2 | 3 | export { BaseElement }; 4 | -------------------------------------------------------------------------------- /phaseD/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './render'; 2 | export * from './types'; 3 | 4 | export const File = 'File'; 5 | -------------------------------------------------------------------------------- /phaseE/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './render'; 2 | export * from './types'; 3 | 4 | export const File = 'File'; 5 | -------------------------------------------------------------------------------- /phaseF/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './render'; 2 | export * from './types'; 3 | 4 | export const File = 'File'; 5 | -------------------------------------------------------------------------------- /slides/assets/react.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clayrisser/create-react-renderer/HEAD/slides/assets/react.png -------------------------------------------------------------------------------- /slides/assets/good-work.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clayrisser/create-react-renderer/HEAD/slides/assets/good-work.gif -------------------------------------------------------------------------------- /assets/create-react-renderer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clayrisser/create-react-renderer/HEAD/assets/create-react-renderer.png -------------------------------------------------------------------------------- /phaseA/tests/index.ts: -------------------------------------------------------------------------------- 1 | describe('react-ast', () => { 2 | it('works', () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /phaseB/tests/index.ts: -------------------------------------------------------------------------------- 1 | describe('react-ast', () => { 2 | it('works', () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /phaseC/tests/index.ts: -------------------------------------------------------------------------------- 1 | describe('react-ast', () => { 2 | it('works', () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /phaseD/tests/index.ts: -------------------------------------------------------------------------------- 1 | describe('react-ast', () => { 2 | it('works', () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /phaseE/tests/index.ts: -------------------------------------------------------------------------------- 1 | describe('react-ast', () => { 2 | it('works', () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /phaseF/tests/index.ts: -------------------------------------------------------------------------------- 1 | describe('react-ast', () => { 2 | it('works', () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /phaseG/tests/index.ts: -------------------------------------------------------------------------------- 1 | describe('react-ast', () => { 2 | it('works', () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /phaseH/tests/index.ts: -------------------------------------------------------------------------------- 1 | describe('react-ast', () => { 2 | it('works', () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /phaseI/tests/index.ts: -------------------------------------------------------------------------------- 1 | describe('react-ast', () => { 2 | it('works', () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /phaseJ/tests/index.ts: -------------------------------------------------------------------------------- 1 | describe('react-ast', () => { 2 | it('works', () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /phaseK/tests/index.ts: -------------------------------------------------------------------------------- 1 | describe('react-ast', () => { 2 | it('works', () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /phaseL/tests/index.ts: -------------------------------------------------------------------------------- 1 | describe('react-ast', () => { 2 | it('works', () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /react-renderer-binding-diagram.epgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clayrisser/create-react-renderer/HEAD/react-renderer-binding-diagram.epgz -------------------------------------------------------------------------------- /slides/assets/baning-head-on-wall.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clayrisser/create-react-renderer/HEAD/slides/assets/baning-head-on-wall.gif -------------------------------------------------------------------------------- /slides/assets/react-renderer-binding-diagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clayrisser/create-react-renderer/HEAD/slides/assets/react-renderer-binding-diagram.jpg -------------------------------------------------------------------------------- /phaseB/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './render'; 2 | export * from './types'; 3 | 4 | export const Hello = 'Hello'; 5 | export const Howdy = 'Howdy'; 6 | export const Wrapper = 'Wrapper'; 7 | -------------------------------------------------------------------------------- /phaseC/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './render'; 2 | export * from './types'; 3 | 4 | export const Hello = 'Hello'; 5 | export const Howdy = 'Howdy'; 6 | export const Wrapper = 'Wrapper'; 7 | -------------------------------------------------------------------------------- /phaseD/src/elements/index.ts: -------------------------------------------------------------------------------- 1 | import File from './File'; 2 | import { IElement } from './BaseElement'; 3 | 4 | export interface Elements { 5 | [key: string]: IElement; 6 | } 7 | 8 | export { File }; 9 | export default { File } as Elements; 10 | -------------------------------------------------------------------------------- /phaseE/src/elements/index.ts: -------------------------------------------------------------------------------- 1 | import File from './File'; 2 | import { IElement } from './BaseElement'; 3 | 4 | export interface Elements { 5 | [key: string]: IElement; 6 | } 7 | 8 | export { File }; 9 | export default { File } as Elements; 10 | -------------------------------------------------------------------------------- /phaseF/src/elements/index.ts: -------------------------------------------------------------------------------- 1 | import File from './File'; 2 | import { IElement } from './BaseElement'; 3 | 4 | export interface Elements { 5 | [key: string]: IElement; 6 | } 7 | 8 | export { File }; 9 | export default { File } as Elements; 10 | -------------------------------------------------------------------------------- /phaseG/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './render'; 2 | export * from './types'; 3 | 4 | export const Ast = 'Ast'; 5 | export const Expression = 'Expression'; 6 | export const File = 'File'; 7 | export const Program = 'Program'; 8 | export const Smart = 'Smart'; 9 | -------------------------------------------------------------------------------- /phaseH/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './render'; 2 | export * from './types'; 3 | 4 | export const Ast = 'Ast'; 5 | export const Expression = 'Expression'; 6 | export const File = 'File'; 7 | export const Program = 'Program'; 8 | export const Smart = 'Smart'; 9 | -------------------------------------------------------------------------------- /phaseI/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './render'; 2 | export * from './types'; 3 | 4 | export const Ast = 'Ast'; 5 | export const Expression = 'Expression'; 6 | export const File = 'File'; 7 | export const Program = 'Program'; 8 | export const Smart = 'Smart'; 9 | -------------------------------------------------------------------------------- /phaseJ/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './render'; 2 | export * from './types'; 3 | 4 | export const Ast = 'Ast'; 5 | export const Expression = 'Expression'; 6 | export const File = 'File'; 7 | export const Program = 'Program'; 8 | export const Smart = 'Smart'; 9 | -------------------------------------------------------------------------------- /phaseK/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './render'; 2 | export * from './types'; 3 | 4 | export const Ast = 'Ast'; 5 | export const Expression = 'Expression'; 6 | export const File = 'File'; 7 | export const Program = 'Program'; 8 | export const Smart = 'Smart'; 9 | -------------------------------------------------------------------------------- /phaseD/src/@types/reactAst.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace JSX { 2 | // @ts-ignore 3 | import { ReactNode, Ref } from 'react'; 4 | 5 | interface IntrinsicElements { 6 | File: { 7 | ref?: Ref; 8 | children?: ReactNode; 9 | }; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /phaseE/src/@types/reactAst.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace JSX { 2 | // @ts-ignore 3 | import { ReactNode, Ref } from 'react'; 4 | 5 | interface IntrinsicElements { 6 | File: { 7 | ref?: Ref; 8 | children?: ReactNode; 9 | }; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /phaseF/src/@types/reactAst.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace JSX { 2 | // @ts-ignore 3 | import { ReactNode, Ref } from 'react'; 4 | 5 | interface IntrinsicElements { 6 | File: { 7 | ref?: Ref; 8 | children?: ReactNode; 9 | }; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /phaseA/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "jam", 5 | { 6 | "targets": { 7 | "node": "6" 8 | } 9 | } 10 | ], 11 | "@babel/typescript", 12 | "@babel/react" 13 | ], 14 | "plugins": ["typescript-to-proptypes"] 15 | } 16 | -------------------------------------------------------------------------------- /phaseB/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "jam", 5 | { 6 | "targets": { 7 | "node": "6" 8 | } 9 | } 10 | ], 11 | "@babel/typescript", 12 | "@babel/react" 13 | ], 14 | "plugins": ["typescript-to-proptypes"] 15 | } 16 | -------------------------------------------------------------------------------- /phaseC/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "jam", 5 | { 6 | "targets": { 7 | "node": "6" 8 | } 9 | } 10 | ], 11 | "@babel/typescript", 12 | "@babel/react" 13 | ], 14 | "plugins": ["typescript-to-proptypes"] 15 | } 16 | -------------------------------------------------------------------------------- /phaseD/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "jam", 5 | { 6 | "targets": { 7 | "node": "6" 8 | } 9 | } 10 | ], 11 | "@babel/typescript", 12 | "@babel/react" 13 | ], 14 | "plugins": ["typescript-to-proptypes"] 15 | } 16 | -------------------------------------------------------------------------------- /phaseE/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "jam", 5 | { 6 | "targets": { 7 | "node": "6" 8 | } 9 | } 10 | ], 11 | "@babel/typescript", 12 | "@babel/react" 13 | ], 14 | "plugins": ["typescript-to-proptypes"] 15 | } 16 | -------------------------------------------------------------------------------- /phaseF/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "jam", 5 | { 6 | "targets": { 7 | "node": "6" 8 | } 9 | } 10 | ], 11 | "@babel/typescript", 12 | "@babel/react" 13 | ], 14 | "plugins": ["typescript-to-proptypes"] 15 | } 16 | -------------------------------------------------------------------------------- /phaseG/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "jam", 5 | { 6 | "targets": { 7 | "node": "6" 8 | } 9 | } 10 | ], 11 | "@babel/typescript", 12 | "@babel/react" 13 | ], 14 | "plugins": ["typescript-to-proptypes"] 15 | } 16 | -------------------------------------------------------------------------------- /phaseH/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "jam", 5 | { 6 | "targets": { 7 | "node": "6" 8 | } 9 | } 10 | ], 11 | "@babel/typescript", 12 | "@babel/react" 13 | ], 14 | "plugins": ["typescript-to-proptypes"] 15 | } 16 | -------------------------------------------------------------------------------- /phaseI/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "jam", 5 | { 6 | "targets": { 7 | "node": "6" 8 | } 9 | } 10 | ], 11 | "@babel/typescript", 12 | "@babel/react" 13 | ], 14 | "plugins": ["typescript-to-proptypes"] 15 | } 16 | -------------------------------------------------------------------------------- /phaseJ/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "jam", 5 | { 6 | "targets": { 7 | "node": "6" 8 | } 9 | } 10 | ], 11 | "@babel/typescript", 12 | "@babel/react" 13 | ], 14 | "plugins": ["typescript-to-proptypes"] 15 | } 16 | -------------------------------------------------------------------------------- /phaseK/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "jam", 5 | { 6 | "targets": { 7 | "node": "6" 8 | } 9 | } 10 | ], 11 | "@babel/typescript", 12 | "@babel/react" 13 | ], 14 | "plugins": ["typescript-to-proptypes"] 15 | } 16 | -------------------------------------------------------------------------------- /phaseL/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "jam", 5 | { 6 | "targets": { 7 | "node": "6" 8 | } 9 | } 10 | ], 11 | "@babel/typescript", 12 | "@babel/react" 13 | ], 14 | "plugins": ["typescript-to-proptypes"] 15 | } 16 | -------------------------------------------------------------------------------- /phaseL/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './components'; 2 | export * from './render'; 3 | export * from './types'; 4 | 5 | export const Ast = 'Ast'; 6 | export const Expression = 'Expression'; 7 | export const File = 'File'; 8 | export const Program = 'Program'; 9 | export const Smart = 'Smart'; 10 | -------------------------------------------------------------------------------- /phaseA/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | indent_size = 2 6 | indent_style = space 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.{js,jsx,ts,tsx,json}] 11 | charset = utf-8 12 | 13 | [*.md] 14 | charset = utf-8 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /phaseB/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | indent_size = 2 6 | indent_style = space 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.{js,jsx,ts,tsx,json}] 11 | charset = utf-8 12 | 13 | [*.md] 14 | charset = utf-8 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /phaseC/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | indent_size = 2 6 | indent_style = space 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.{js,jsx,ts,tsx,json}] 11 | charset = utf-8 12 | 13 | [*.md] 14 | charset = utf-8 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /phaseD/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | indent_size = 2 6 | indent_style = space 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.{js,jsx,ts,tsx,json}] 11 | charset = utf-8 12 | 13 | [*.md] 14 | charset = utf-8 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /phaseE/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | indent_size = 2 6 | indent_style = space 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.{js,jsx,ts,tsx,json}] 11 | charset = utf-8 12 | 13 | [*.md] 14 | charset = utf-8 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /phaseF/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | indent_size = 2 6 | indent_style = space 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.{js,jsx,ts,tsx,json}] 11 | charset = utf-8 12 | 13 | [*.md] 14 | charset = utf-8 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /phaseG/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | indent_size = 2 6 | indent_style = space 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.{js,jsx,ts,tsx,json}] 11 | charset = utf-8 12 | 13 | [*.md] 14 | charset = utf-8 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /phaseH/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | indent_size = 2 6 | indent_style = space 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.{js,jsx,ts,tsx,json}] 11 | charset = utf-8 12 | 13 | [*.md] 14 | charset = utf-8 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /phaseI/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | indent_size = 2 6 | indent_style = space 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.{js,jsx,ts,tsx,json}] 11 | charset = utf-8 12 | 13 | [*.md] 14 | charset = utf-8 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /phaseJ/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | indent_size = 2 6 | indent_style = space 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.{js,jsx,ts,tsx,json}] 11 | charset = utf-8 12 | 13 | [*.md] 14 | charset = utf-8 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /phaseK/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | indent_size = 2 6 | indent_style = space 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.{js,jsx,ts,tsx,json}] 11 | charset = utf-8 12 | 13 | [*.md] 14 | charset = utf-8 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /phaseL/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | indent_size = 2 6 | indent_style = space 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.{js,jsx,ts,tsx,json}] 11 | charset = utf-8 12 | 13 | [*.md] 14 | charset = utf-8 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /phaseL/src/components/Code/Code.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Smart } from '../..'; 3 | 4 | export interface CodeProps { 5 | children: string; 6 | } 7 | 8 | export class Code extends Component { 9 | render() { 10 | return ; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /phaseB/src/elements/Hello.ts: -------------------------------------------------------------------------------- 1 | import BaseElement from './BaseElement'; 2 | import { Props } from '../types'; 3 | 4 | export default class Hello extends BaseElement { 5 | static propTypes: object; 6 | 7 | static defaultProps: Props; 8 | 9 | constructor(props: Props = {}) { 10 | super({ hello: 'world' }, props); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /phaseB/src/elements/Howdy.ts: -------------------------------------------------------------------------------- 1 | import BaseElement from './BaseElement'; 2 | import { Props } from '../types'; 3 | 4 | export default class Howdy extends BaseElement { 5 | static propTypes: object; 6 | 7 | static defaultProps: Props; 8 | 9 | constructor(props: Props = {}) { 10 | super({ howdy: 'texas' }, props); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /phaseC/src/elements/Hello.ts: -------------------------------------------------------------------------------- 1 | import BaseElement from './BaseElement'; 2 | import { Props } from '../types'; 3 | 4 | export default class Hello extends BaseElement { 5 | static propTypes: object; 6 | 7 | static defaultProps: Props; 8 | 9 | constructor(props: Props = {}) { 10 | super({ hello: 'world' }, props); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /phaseC/src/elements/Howdy.ts: -------------------------------------------------------------------------------- 1 | import BaseElement from './BaseElement'; 2 | import { Props } from '../types'; 3 | 4 | export default class Howdy extends BaseElement { 5 | static propTypes: object; 6 | 7 | static defaultProps: Props; 8 | 9 | constructor(props: Props = {}) { 10 | super({ howdy: 'texas' }, props); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /phaseB/src/elements/Wrapper.ts: -------------------------------------------------------------------------------- 1 | import BaseElement from './BaseElement'; 2 | import { Props } from '../types'; 3 | 4 | export default class Wrapper extends BaseElement { 5 | static propTypes: object; 6 | 7 | static defaultProps: Props; 8 | 9 | constructor(props: Props = {}) { 10 | super({ cool: 'beans' }, props); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /phaseB/src/createElement.ts: -------------------------------------------------------------------------------- 1 | import elements from './elements'; 2 | import { IElement } from './elements/BaseElement'; 3 | 4 | export default function createElement(elementType: string, props: any) { 5 | const Element: IElement = elements[elementType]; 6 | if (!Element) throw new Error(`unknown element of type '${elementType}'`); 7 | return new Element(props); 8 | } 9 | -------------------------------------------------------------------------------- /phaseC/src/createElement.ts: -------------------------------------------------------------------------------- 1 | import elements from './elements'; 2 | import { IElement } from './elements/BaseElement'; 3 | 4 | export default function createElement(elementType: string, props: any) { 5 | const Element: IElement = elements[elementType]; 6 | if (!Element) throw new Error(`unknown element of type '${elementType}'`); 7 | return new Element(props); 8 | } 9 | -------------------------------------------------------------------------------- /phaseD/src/createElement.ts: -------------------------------------------------------------------------------- 1 | import elements from './elements'; 2 | import { IElement } from './elements/BaseElement'; 3 | 4 | export default function createElement(elementType: string, props: any) { 5 | const Element: IElement = elements[elementType]; 6 | if (!Element) throw new Error(`unknown element of type '${elementType}'`); 7 | return new Element(props); 8 | } 9 | -------------------------------------------------------------------------------- /phaseE/src/createElement.ts: -------------------------------------------------------------------------------- 1 | import elements from './elements'; 2 | import { IElement } from './elements/BaseElement'; 3 | 4 | export default function createElement(elementType: string, props: any) { 5 | const Element: IElement = elements[elementType]; 6 | if (!Element) throw new Error(`unknown element of type '${elementType}'`); 7 | return new Element(props); 8 | } 9 | -------------------------------------------------------------------------------- /phaseF/src/createElement.ts: -------------------------------------------------------------------------------- 1 | import elements from './elements'; 2 | import { IElement } from './elements/BaseElement'; 3 | 4 | export default function createElement(elementType: string, props: any) { 5 | const Element: IElement = elements[elementType]; 6 | if (!Element) throw new Error(`unknown element of type '${elementType}'`); 7 | return new Element(props); 8 | } 9 | -------------------------------------------------------------------------------- /phaseG/src/createElement.ts: -------------------------------------------------------------------------------- 1 | import elements from './elements'; 2 | import { IElement } from './elements/BaseElement'; 3 | 4 | export default function createElement(elementType: string, props: any) { 5 | const Element: IElement = elements[elementType]; 6 | if (!Element) throw new Error(`unknown element of type '${elementType}'`); 7 | return new Element(props); 8 | } 9 | -------------------------------------------------------------------------------- /phaseH/src/createElement.ts: -------------------------------------------------------------------------------- 1 | import elements from './elements'; 2 | import { IElement } from './elements/BaseElement'; 3 | 4 | export default function createElement(elementType: string, props: any) { 5 | const Element: IElement = elements[elementType]; 6 | if (!Element) throw new Error(`unknown element of type '${elementType}'`); 7 | return new Element(props); 8 | } 9 | -------------------------------------------------------------------------------- /phaseI/src/createElement.ts: -------------------------------------------------------------------------------- 1 | import elements from './elements'; 2 | import { IElement } from './elements/BaseElement'; 3 | 4 | export default function createElement(elementType: string, props: any) { 5 | const Element: IElement = elements[elementType]; 6 | if (!Element) throw new Error(`unknown element of type '${elementType}'`); 7 | return new Element(props); 8 | } 9 | -------------------------------------------------------------------------------- /phaseJ/src/createElement.ts: -------------------------------------------------------------------------------- 1 | import elements from './elements'; 2 | import { IElement } from './elements/BaseElement'; 3 | 4 | export default function createElement(elementType: string, props: any) { 5 | const Element: IElement = elements[elementType]; 6 | if (!Element) throw new Error(`unknown element of type '${elementType}'`); 7 | return new Element(props); 8 | } 9 | -------------------------------------------------------------------------------- /phaseG/src/elements/Program.ts: -------------------------------------------------------------------------------- 1 | import t from '@babel/types'; 2 | import BaseElement from './BaseElement'; 3 | import { Props } from '../types'; 4 | 5 | export default class Program extends BaseElement { 6 | static propTypes: object; 7 | 8 | static defaultProps: Props; 9 | 10 | constructor(props: Props = {}) { 11 | super(t.program([]), props); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /phaseH/src/elements/Program.ts: -------------------------------------------------------------------------------- 1 | import t from '@babel/types'; 2 | import BaseElement from './BaseElement'; 3 | import { Props } from '../types'; 4 | 5 | export default class Program extends BaseElement { 6 | static propTypes: object; 7 | 8 | static defaultProps: Props; 9 | 10 | constructor(props: Props = {}) { 11 | super(t.program([]), props); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /phaseI/src/elements/Program.ts: -------------------------------------------------------------------------------- 1 | import t from '@babel/types'; 2 | import BaseElement from './BaseElement'; 3 | import { Props } from '../types'; 4 | 5 | export default class Program extends BaseElement { 6 | static propTypes: object; 7 | 8 | static defaultProps: Props; 9 | 10 | constructor(props: Props = {}) { 11 | super(t.program([]), props); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /phaseJ/src/elements/Program.ts: -------------------------------------------------------------------------------- 1 | import t from '@babel/types'; 2 | import BaseElement from './BaseElement'; 3 | import { Props } from '../types'; 4 | 5 | export default class Program extends BaseElement { 6 | static propTypes: object; 7 | 8 | static defaultProps: Props; 9 | 10 | constructor(props: Props = {}) { 11 | super(t.program([]), props); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /phaseK/src/elements/Program.ts: -------------------------------------------------------------------------------- 1 | import t from '@babel/types'; 2 | import BaseElement from './BaseElement'; 3 | import { Props } from '../types'; 4 | 5 | export default class Program extends BaseElement { 6 | static propTypes: object; 7 | 8 | static defaultProps: Props; 9 | 10 | constructor(props: Props = {}) { 11 | super(t.program([]), props); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /phaseL/src/elements/Program.ts: -------------------------------------------------------------------------------- 1 | import t from '@babel/types'; 2 | import BaseElement from './BaseElement'; 3 | import { Props } from '../types'; 4 | 5 | export default class Program extends BaseElement { 6 | static propTypes: object; 7 | 8 | static defaultProps: Props; 9 | 10 | constructor(props: Props = {}) { 11 | super(t.program([]), props); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /phaseB/src/elements/index.ts: -------------------------------------------------------------------------------- 1 | import Hello from './Hello'; 2 | import Howdy from './Howdy'; 3 | import Wrapper from './Wrapper'; 4 | import { IElement } from './BaseElement'; 5 | 6 | export interface Elements { 7 | [key: string]: IElement; 8 | } 9 | 10 | export { Hello, Howdy, Wrapper }; 11 | export default { 12 | Hello, 13 | Howdy, 14 | Wrapper 15 | } as Elements; 16 | -------------------------------------------------------------------------------- /phaseC/src/elements/index.ts: -------------------------------------------------------------------------------- 1 | import Hello from './Hello'; 2 | import Howdy from './Howdy'; 3 | import Wrapper from './Wrapper'; 4 | import { IElement } from './BaseElement'; 5 | 6 | export interface Elements { 7 | [key: string]: IElement; 8 | } 9 | 10 | export { Hello, Howdy, Wrapper }; 11 | export default { 12 | Hello, 13 | Howdy, 14 | Wrapper 15 | } as Elements; 16 | -------------------------------------------------------------------------------- /phaseL/example/Body.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from 'react'; 2 | import { JsxElement } from '../src'; 3 | 4 | export interface BodyProps { 5 | hello?: string; 6 | } 7 | 8 | const Body: FC = (props: BodyProps) => ( 9 | {props} 10 | ); 11 | Body.defaultProps = { 12 | hello: 'world' 13 | }; 14 | 15 | export default Body; 16 | -------------------------------------------------------------------------------- /phaseB/src/@types/reactAst.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace JSX { 2 | // @ts-ignore 3 | import { ReactNode, Ref } from 'react'; 4 | 5 | interface IntrinsicElements { 6 | Hello: { 7 | ref?: Ref; 8 | }; 9 | Howdy: { 10 | ref?: Ref; 11 | }; 12 | Wrapper: { 13 | ref?: Ref; 14 | children?: ReactNode; 15 | }; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /phaseC/src/@types/reactAst.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace JSX { 2 | // @ts-ignore 3 | import { ReactNode, Ref } from 'react'; 4 | 5 | interface IntrinsicElements { 6 | Hello: { 7 | ref?: Ref; 8 | }; 9 | Howdy: { 10 | ref?: Ref; 11 | }; 12 | Wrapper: { 13 | ref?: Ref; 14 | children?: ReactNode; 15 | }; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /phaseE/src/util.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import { Path } from './types'; 3 | 4 | export function flattenPath(path?: Path | undefined): string { 5 | if (typeof path !== 'number' && !path) return ''; 6 | if (!Array.isArray(path)) return path.toString(); 7 | return _.flattenDeep(path) 8 | .filter((s: number | string) => s.toString().length) 9 | .join('.'); 10 | } 11 | -------------------------------------------------------------------------------- /phaseF/src/util.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import { Path } from './types'; 3 | 4 | export function flattenPath(path?: Path | undefined): string { 5 | if (typeof path !== 'number' && !path) return ''; 6 | if (!Array.isArray(path)) return path.toString(); 7 | return _.flattenDeep(path) 8 | .filter((s: number | string) => s.toString().length) 9 | .join('.'); 10 | } 11 | -------------------------------------------------------------------------------- /phaseG/src/util.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import { Path } from './types'; 3 | 4 | export function flattenPath(path?: Path | undefined): string { 5 | if (typeof path !== 'number' && !path) return ''; 6 | if (!Array.isArray(path)) return path.toString(); 7 | return _.flattenDeep(path) 8 | .filter((s: number | string) => s.toString().length) 9 | .join('.'); 10 | } 11 | -------------------------------------------------------------------------------- /phaseH/src/util.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import { Path } from './types'; 3 | 4 | export function flattenPath(path?: Path | undefined): string { 5 | if (typeof path !== 'number' && !path) return ''; 6 | if (!Array.isArray(path)) return path.toString(); 7 | return _.flattenDeep(path) 8 | .filter((s: number | string) => s.toString().length) 9 | .join('.'); 10 | } 11 | -------------------------------------------------------------------------------- /phaseI/src/util.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import { Path } from './types'; 3 | 4 | export function flattenPath(path?: Path | undefined): string { 5 | if (typeof path !== 'number' && !path) return ''; 6 | if (!Array.isArray(path)) return path.toString(); 7 | return _.flattenDeep(path) 8 | .filter((s: number | string) => s.toString().length) 9 | .join('.'); 10 | } 11 | -------------------------------------------------------------------------------- /phaseJ/src/util.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import { Path } from './types'; 3 | 4 | export function flattenPath(path?: Path | undefined): string { 5 | if (typeof path !== 'number' && !path) return ''; 6 | if (!Array.isArray(path)) return path.toString(); 7 | return _.flattenDeep(path) 8 | .filter((s: number | string) => s.toString().length) 9 | .join('.'); 10 | } 11 | -------------------------------------------------------------------------------- /phaseK/src/util.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import { Path } from './types'; 3 | 4 | export function flattenPath(path?: Path | undefined): string { 5 | if (typeof path !== 'number' && !path) return ''; 6 | if (!Array.isArray(path)) return path.toString(); 7 | return _.flattenDeep(path) 8 | .filter((s: number | string) => s.toString().length) 9 | .join('.'); 10 | } 11 | -------------------------------------------------------------------------------- /phaseL/src/components/Code/Code.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Code } from './Code'; 3 | import { render } from '../..'; 4 | 5 | describe('', () => { 6 | it('renders', () => { 7 | const code = render(const hello = 'world', { 8 | prettier: false 9 | }); 10 | expect(code).toBe("const hello = 'world';"); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /phaseL/src/util.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import { Path } from './types'; 3 | 4 | export function flattenPath(path?: Path | undefined): string { 5 | if (typeof path !== 'number' && !path) return ''; 6 | if (!Array.isArray(path)) return path.toString(); 7 | return _.flattenDeep(path) 8 | .filter((s: number | string) => s.toString().length) 9 | .join('.'); 10 | } 11 | -------------------------------------------------------------------------------- /phaseD/src/elements/File.ts: -------------------------------------------------------------------------------- 1 | import * as t from '@babel/types'; 2 | import BaseElement from './BaseElement'; 3 | import { Props } from '../types'; 4 | 5 | export default class File extends BaseElement { 6 | static propTypes: object; 7 | 8 | static defaultProps: Props; 9 | 10 | constructor(props: Props = {}) { 11 | super(t.file(t.program([]), [], []), props); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /phaseE/src/elements/File.ts: -------------------------------------------------------------------------------- 1 | import * as t from '@babel/types'; 2 | import BaseElement from './BaseElement'; 3 | import { Props } from '../types'; 4 | 5 | export default class File extends BaseElement { 6 | static propTypes: object; 7 | 8 | static defaultProps: Props; 9 | 10 | constructor(props: Props = {}) { 11 | super(t.file(t.program([]), [], []), props); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /phaseF/src/elements/File.ts: -------------------------------------------------------------------------------- 1 | import * as t from '@babel/types'; 2 | import BaseElement from './BaseElement'; 3 | import { Props } from '../types'; 4 | 5 | export default class File extends BaseElement { 6 | static propTypes: object; 7 | 8 | static defaultProps: Props; 9 | 10 | constructor(props: Props = {}) { 11 | super(t.file(t.program([]), [], []), props); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /phaseA/example/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import util from 'util'; 3 | import { render } from '../src'; 4 | 5 | console.log('======== RECONCILER LIFECYCLE ========'); 6 | const renderedOutput = render(<>); 7 | 8 | console.log('\n\n======== RENDERED OUTPUT ========'); 9 | console.log(util.inspect(renderedOutput, false, null, true)); 10 | console.log('\n\n--------------'); 11 | -------------------------------------------------------------------------------- /phaseD/example/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import util from 'util'; 3 | import { render } from '../src'; 4 | 5 | console.log('======== RECONCILER LIFECYCLE ========'); 6 | const renderedOutput = render(<>); 7 | 8 | console.log('\n\n======== RENDERED OUTPUT ========'); 9 | console.log(util.inspect(renderedOutput, false, null, true)); 10 | console.log('\n\n--------------'); 11 | -------------------------------------------------------------------------------- /phaseE/example/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import util from 'util'; 3 | import { render } from '../src'; 4 | 5 | console.log('======== RECONCILER LIFECYCLE ========'); 6 | const renderedOutput = render(<>); 7 | 8 | console.log('\n\n======== RENDERED OUTPUT ========'); 9 | console.log(util.inspect(renderedOutput, false, null, true)); 10 | console.log('\n\n--------------'); 11 | -------------------------------------------------------------------------------- /phaseF/example/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import util from 'util'; 3 | import { render } from '../src'; 4 | 5 | console.log('======== RECONCILER LIFECYCLE ========'); 6 | const renderedOutput = render(<>); 7 | 8 | console.log('\n\n======== RENDERED OUTPUT ========'); 9 | console.log(util.inspect(renderedOutput, false, null, true)); 10 | console.log('\n\n--------------'); 11 | -------------------------------------------------------------------------------- /phaseL/src/components/CallExpression/CallExpression.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { CallExpression } from './CallExpression'; 3 | import { render } from '../..'; 4 | 5 | describe('', () => { 6 | it('renders', () => { 7 | const code = render(, { prettier: false }); 8 | expect(code).toBe('hello()'); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /phaseG/src/elements/File.ts: -------------------------------------------------------------------------------- 1 | import * as t from '@babel/types'; 2 | import BaseElement from './BaseElement'; 3 | import { Props } from '../types'; 4 | 5 | export default class File extends BaseElement { 6 | static propTypes: object; 7 | 8 | static defaultProps: Props; 9 | 10 | constructor(props: Props = {}) { 11 | super(t.file(t.program([]), [], []), props, { bodyPath: 'program.body' }); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /phaseH/src/elements/File.ts: -------------------------------------------------------------------------------- 1 | import * as t from '@babel/types'; 2 | import BaseElement from './BaseElement'; 3 | import { Props } from '../types'; 4 | 5 | export default class File extends BaseElement { 6 | static propTypes: object; 7 | 8 | static defaultProps: Props; 9 | 10 | constructor(props: Props = {}) { 11 | super(t.file(t.program([]), [], []), props, { bodyPath: 'program.body' }); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /phaseI/src/elements/File.ts: -------------------------------------------------------------------------------- 1 | import * as t from '@babel/types'; 2 | import BaseElement from './BaseElement'; 3 | import { Props } from '../types'; 4 | 5 | export default class File extends BaseElement { 6 | static propTypes: object; 7 | 8 | static defaultProps: Props; 9 | 10 | constructor(props: Props = {}) { 11 | super(t.file(t.program([]), [], []), props, { bodyPath: 'program.body' }); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /phaseJ/src/elements/File.ts: -------------------------------------------------------------------------------- 1 | import * as t from '@babel/types'; 2 | import BaseElement from './BaseElement'; 3 | import { Props } from '../types'; 4 | 5 | export default class File extends BaseElement { 6 | static propTypes: object; 7 | 8 | static defaultProps: Props; 9 | 10 | constructor(props: Props = {}) { 11 | super(t.file(t.program([]), [], []), props, { bodyPath: 'program.body' }); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /phaseK/src/elements/File.ts: -------------------------------------------------------------------------------- 1 | import * as t from '@babel/types'; 2 | import BaseElement from './BaseElement'; 3 | import { Props } from '../types'; 4 | 5 | export default class File extends BaseElement { 6 | static propTypes: object; 7 | 8 | static defaultProps: Props; 9 | 10 | constructor(props: Props = {}) { 11 | super(t.file(t.program([]), [], []), props, { bodyPath: 'program.body' }); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /phaseL/src/elements/File.ts: -------------------------------------------------------------------------------- 1 | import * as t from '@babel/types'; 2 | import BaseElement from './BaseElement'; 3 | import { Props } from '../types'; 4 | 5 | export default class File extends BaseElement { 6 | static propTypes: object; 7 | 8 | static defaultProps: Props; 9 | 10 | constructor(props: Props = {}) { 11 | super(t.file(t.program([]), [], []), props, { bodyPath: 'program.body' }); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /phaseI/src/dev.ts: -------------------------------------------------------------------------------- 1 | const { env } = process; 2 | 3 | function isDev(): boolean { 4 | if (typeof env.NODE_ENV === 'undefined') { 5 | return typeof env.__DEV__ === 'undefined' 6 | ? false 7 | : env.__DEV__.toLowerCase() !== 'false'; 8 | } 9 | return ( 10 | env.NODE_ENV.toLowerCase() !== 'prod' || 11 | env.NODE_ENV.toLowerCase() !== 'production' 12 | ); 13 | } 14 | 15 | export default isDev(); 16 | -------------------------------------------------------------------------------- /phaseJ/src/dev.ts: -------------------------------------------------------------------------------- 1 | const { env } = process; 2 | 3 | function isDev(): boolean { 4 | if (typeof env.NODE_ENV === 'undefined') { 5 | return typeof env.__DEV__ === 'undefined' 6 | ? false 7 | : env.__DEV__.toLowerCase() !== 'false'; 8 | } 9 | return ( 10 | env.NODE_ENV.toLowerCase() !== 'prod' || 11 | env.NODE_ENV.toLowerCase() !== 'production' 12 | ); 13 | } 14 | 15 | export default isDev(); 16 | -------------------------------------------------------------------------------- /phaseK/src/dev.ts: -------------------------------------------------------------------------------- 1 | const { env } = process; 2 | 3 | function isDev(): boolean { 4 | if (typeof env.NODE_ENV === 'undefined') { 5 | return typeof env.__DEV__ === 'undefined' 6 | ? false 7 | : env.__DEV__.toLowerCase() !== 'false'; 8 | } 9 | return ( 10 | env.NODE_ENV.toLowerCase() !== 'prod' || 11 | env.NODE_ENV.toLowerCase() !== 'production' 12 | ); 13 | } 14 | 15 | export default isDev(); 16 | -------------------------------------------------------------------------------- /phaseL/src/dev.ts: -------------------------------------------------------------------------------- 1 | const { env } = process; 2 | 3 | function isDev(): boolean { 4 | if (typeof env.NODE_ENV === 'undefined') { 5 | return typeof env.__DEV__ === 'undefined' 6 | ? false 7 | : env.__DEV__.toLowerCase() !== 'false'; 8 | } 9 | return ( 10 | env.NODE_ENV.toLowerCase() !== 'prod' || 11 | env.NODE_ENV.toLowerCase() !== 'production' 12 | ); 13 | } 14 | 15 | export default isDev(); 16 | -------------------------------------------------------------------------------- /phaseK/example/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render, Smart } from '../src'; 3 | 4 | console.log('======== RECONCILER LIFECYCLE ========'); 5 | const renderedOutput = render( 6 | <> 7 | 8 | const howdy = () => 'texas' 9 | 10 | ); 11 | 12 | console.log('\n\n======== RENDERED OUTPUT ========'); 13 | console.log(renderedOutput); 14 | console.log('\n\n--------------'); 15 | -------------------------------------------------------------------------------- /phaseC/src/elements/Wrapper.ts: -------------------------------------------------------------------------------- 1 | import BaseElement from './BaseElement'; 2 | import { Props } from '../types'; 3 | 4 | export default class Wrapper extends BaseElement { 5 | static propTypes: object; 6 | 7 | static defaultProps: Props; 8 | 9 | constructor(props: Props = {}) { 10 | super({ greetings: [] }, props); 11 | } 12 | 13 | appendChild(child: BaseElement) { 14 | this.node.greetings.push(child.node); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /phaseG/src/elements/index.ts: -------------------------------------------------------------------------------- 1 | import Ast from './Ast'; 2 | import Expression from './Expression'; 3 | import File from './File'; 4 | import Program from './Program'; 5 | import Smart from './Smart'; 6 | import { IElement } from './BaseElement'; 7 | 8 | export interface Elements { 9 | [key: string]: IElement; 10 | } 11 | 12 | export { Ast, Expression, File, Program, Smart }; 13 | export default { Ast, Expression, File, Program, Smart } as Elements; 14 | -------------------------------------------------------------------------------- /phaseH/src/elements/index.ts: -------------------------------------------------------------------------------- 1 | import Ast from './Ast'; 2 | import Expression from './Expression'; 3 | import File from './File'; 4 | import Program from './Program'; 5 | import Smart from './Smart'; 6 | import { IElement } from './BaseElement'; 7 | 8 | export interface Elements { 9 | [key: string]: IElement; 10 | } 11 | 12 | export { Ast, Expression, File, Program, Smart }; 13 | export default { Ast, Expression, File, Program, Smart } as Elements; 14 | -------------------------------------------------------------------------------- /phaseI/src/elements/index.ts: -------------------------------------------------------------------------------- 1 | import Ast from './Ast'; 2 | import Expression from './Expression'; 3 | import File from './File'; 4 | import Program from './Program'; 5 | import Smart from './Smart'; 6 | import { IElement } from './BaseElement'; 7 | 8 | export interface Elements { 9 | [key: string]: IElement; 10 | } 11 | 12 | export { Ast, Expression, File, Program, Smart }; 13 | export default { Ast, Expression, File, Program, Smart } as Elements; 14 | -------------------------------------------------------------------------------- /phaseJ/src/elements/index.ts: -------------------------------------------------------------------------------- 1 | import Ast from './Ast'; 2 | import Expression from './Expression'; 3 | import File from './File'; 4 | import Program from './Program'; 5 | import Smart from './Smart'; 6 | import { IElement } from './BaseElement'; 7 | 8 | export interface Elements { 9 | [key: string]: IElement; 10 | } 11 | 12 | export { Ast, Expression, File, Program, Smart }; 13 | export default { Ast, Expression, File, Program, Smart } as Elements; 14 | -------------------------------------------------------------------------------- /phaseK/src/elements/index.ts: -------------------------------------------------------------------------------- 1 | import Ast from './Ast'; 2 | import Expression from './Expression'; 3 | import File from './File'; 4 | import Program from './Program'; 5 | import Smart from './Smart'; 6 | import { IElement } from './BaseElement'; 7 | 8 | export interface Elements { 9 | [key: string]: IElement; 10 | } 11 | 12 | export { Ast, Expression, File, Program, Smart }; 13 | export default { Ast, Expression, File, Program, Smart } as Elements; 14 | -------------------------------------------------------------------------------- /phaseL/src/elements/index.ts: -------------------------------------------------------------------------------- 1 | import Ast from './Ast'; 2 | import Expression from './Expression'; 3 | import File from './File'; 4 | import Program from './Program'; 5 | import Smart from './Smart'; 6 | import { IElement } from './BaseElement'; 7 | 8 | export interface Elements { 9 | [key: string]: IElement; 10 | } 11 | 12 | export { Ast, Expression, File, Program, Smart }; 13 | export default { Ast, Expression, File, Program, Smart } as Elements; 14 | -------------------------------------------------------------------------------- /phaseB/example/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import util from 'util'; 3 | import { render, Hello, Howdy } from '../src'; 4 | 5 | console.log('======== RECONCILER LIFECYCLE ========'); 6 | const renderedOutput = render( 7 | <> 8 | 9 | 10 | 11 | ); 12 | 13 | console.log('\n\n======== RENDERED OUTPUT ========'); 14 | console.log(util.inspect(renderedOutput, false, null, true)); 15 | console.log('\n\n--------------'); 16 | -------------------------------------------------------------------------------- /phaseG/example/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import util from 'util'; 3 | import { render, Smart } from '../src'; 4 | 5 | console.log('======== RECONCILER LIFECYCLE ========'); 6 | const renderedOutput = render( 7 | <> 8 | 9 | 10 | ); 11 | 12 | console.log('\n\n======== RENDERED OUTPUT ========'); 13 | console.log(util.inspect(renderedOutput, false, null, true)); 14 | console.log('\n\n--------------'); 15 | -------------------------------------------------------------------------------- /phaseK/src/createElement.ts: -------------------------------------------------------------------------------- 1 | import elements from './elements'; 2 | import { IElement } from './elements/BaseElement'; 3 | import { getContext } from './context'; 4 | 5 | export default function createElement(elementType: string, props: any) { 6 | const { parserOptions } = getContext(); 7 | const Element: IElement = elements[elementType]; 8 | if (!Element) throw new Error(`unknown element of type '${elementType}'`); 9 | return new Element(props, parserOptions); 10 | } 11 | -------------------------------------------------------------------------------- /phaseL/src/createElement.ts: -------------------------------------------------------------------------------- 1 | import elements from './elements'; 2 | import { IElement } from './elements/BaseElement'; 3 | import { getContext } from './context'; 4 | 5 | export default function createElement(elementType: string, props: any) { 6 | const { parserOptions } = getContext(); 7 | const Element: IElement = elements[elementType]; 8 | if (!Element) throw new Error(`unknown element of type '${elementType}'`); 9 | return new Element(props, parserOptions); 10 | } 11 | -------------------------------------------------------------------------------- /phaseL/src/components/ClassDeclaration/ClassDeclaration.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ClassDeclaration } from './ClassDeclaration'; 3 | import { render } from '../..'; 4 | 5 | describe('', () => { 6 | it('renders', () => { 7 | const code = render( 8 | , 9 | { prettier: false } 10 | ); 11 | expect(code).toBe('class Button extends Component {}'); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /slides/.eslintrc: -------------------------------------------------------------------------------- 1 | --- 2 | "extends": 3 | - "formidable/configurations/es6-react" 4 | 5 | "rules": 6 | "indent": [2, 2, {"SwitchCase": 1}] 7 | "max-len": 0 8 | "no-magic-numbers": 0 9 | "react/prefer-es6-class": 0 10 | "react/no-multi-comp": 0 11 | "quotes": [2, "single"] 12 | "env": 13 | "browser": true, 14 | "node": true 15 | "globals": 16 | "afterEach": true, 17 | "describe": true, 18 | "expect": true, 19 | "it": true, 20 | "jest": true, 21 | "test": true 22 | -------------------------------------------------------------------------------- /phaseC/example/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import util from 'util'; 3 | import { render, Hello, Howdy } from '../src'; 4 | 5 | console.log('======== RECONCILER LIFECYCLE ========'); 6 | const renderedOutput = render( 7 | <> 8 | 9 | 10 | 11 | 12 | 13 | ); 14 | 15 | console.log('\n\n======== RENDERED OUTPUT ========'); 16 | console.log(util.inspect(renderedOutput, false, null, true)); 17 | console.log('\n\n--------------'); 18 | -------------------------------------------------------------------------------- /phaseH/example/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import util from 'util'; 3 | import { render, Smart } from '../src'; 4 | 5 | console.log('======== RECONCILER LIFECYCLE ========'); 6 | const renderedOutput = render( 7 | <> 8 | 9 | const howdy = () => 'texas' 10 | 11 | ); 12 | 13 | console.log('\n\n======== RENDERED OUTPUT ========'); 14 | console.log(util.inspect(renderedOutput, false, null, true)); 15 | console.log('\n\n--------------'); 16 | -------------------------------------------------------------------------------- /phaseI/example/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import util from 'util'; 3 | import { render, Smart } from '../src'; 4 | 5 | console.log('======== RECONCILER LIFECYCLE ========'); 6 | const renderedOutput = render( 7 | <> 8 | 9 | const howdy = () => 'texas' 10 | 11 | ); 12 | 13 | console.log('\n\n======== RENDERED OUTPUT ========'); 14 | console.log(util.inspect(renderedOutput, false, null, true)); 15 | console.log('\n\n--------------'); 16 | -------------------------------------------------------------------------------- /phaseL/src/components/Param/Param.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { FunctionDeclaration } from '../FunctionDeclaration'; 3 | import { Param } from './Param'; 4 | import { render } from '../..'; 5 | 6 | describe('', () => { 7 | it('renders', () => { 8 | const code = render( 9 | 10 | p 11 | , 12 | { prettier: false } 13 | ); 14 | expect(code).toBe('function f(p) {}'); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /slides/presentation/slides/Spoiler.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | BlockQuote, 4 | Cite, 5 | Deck, 6 | Heading, 7 | Image, 8 | List, 9 | ListItem, 10 | Notes, 11 | Quote, 12 | Slide, 13 | Text 14 | } from 'spectacle'; 15 | 16 | const Home = () => ( 17 | 18 | 19 | I thought this was 20 |
a NodeJS meetup? 21 |
22 |
23 | ); 24 | 25 | export default Home; 26 | -------------------------------------------------------------------------------- /phaseG/README.md: -------------------------------------------------------------------------------- 1 | # Phase G 2 | 3 | > create base elements 4 | 5 | ## Steps 6 | 7 | ### Create element constants 8 | 9 | ### Create intrinsic element types 10 | 11 | ### Create elements 12 | 13 | Remember elements should extend the BaseElement 14 | 15 | ## Interesting Files 16 | 17 | [src/index.ts](src/index.ts) 18 | 19 | [src/@types/reactAst.d.ts](src/@types/reactAst.d.ts) 20 | 21 | [src/elements/Smart.ts](src/elements/Smart.ts) 22 | 23 | [src/elements/index.ts](src/elements/index.ts) 24 | 25 | ## Demo 26 | 27 | ```sh 28 | npm run start 29 | ``` 30 | -------------------------------------------------------------------------------- /phaseL/src/components/JsxAttribute/JsxAttribute.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { JsxElement } from '../JsxElement'; 3 | import { render } from '../..'; 4 | 5 | describe('', () => { 6 | it('renders', () => { 7 | const code = render( 8 | , 9 | { 10 | parserOptions: { 11 | plugins: ['jsx'] 12 | }, 13 | prettier: false 14 | } 15 | ); 16 | expect(code).toBe(''); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /phaseL/src/components/ExportNamedDeclaration/ExportNamedDeclaration.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component, ReactNode } from 'react'; 2 | import { Smart } from '../..'; 3 | 4 | export interface ExportNamedDeclarationProps { 5 | children: ReactNode; 6 | } 7 | 8 | export class ExportNamedDeclaration extends Component< 9 | ExportNamedDeclarationProps 10 | > { 11 | render() { 12 | const code = `export class C{}`; 13 | return ( 14 | 15 | {this.props.children} 16 | 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /phaseL/README.md: -------------------------------------------------------------------------------- 1 | # Phase L 2 | 3 | > create components 4 | 5 | ## Steps 6 | 7 | Just write react components like you normally would using the elements as your foundation. 8 | 9 | Notice that most of the code is the high level components. That is because components are 10 | much easier to build than elements. It's easier to build a few broad and general elements 11 | and then build lots of specific components on top of the broad elements. 12 | 13 | ## Interesting Files 14 | 15 | [src/components](src/components) 16 | 17 | ## Demo 18 | 19 | ```sh 20 | npm run start 21 | ``` 22 | -------------------------------------------------------------------------------- /phaseL/src/components/ExportDefaultDeclaration/ExportDefaultDeclaration.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component, ReactNode } from 'react'; 2 | import { Smart } from '../..'; 3 | 4 | export interface ExportDefaultDeclarationProps { 5 | children: ReactNode; 6 | } 7 | 8 | export class ExportDefaultDeclaration extends Component< 9 | ExportDefaultDeclarationProps 10 | > { 11 | render() { 12 | const code = `export default class C{}`; 13 | return ( 14 | 15 | {this.props.children} 16 | 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /slides/presentation/slides/Phase.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | BlockQuote, 4 | Markdown, 5 | Cite, 6 | Deck, 7 | Heading, 8 | Image, 9 | List, 10 | ListItem, 11 | Notes, 12 | Quote, 13 | Slide, 14 | Text 15 | } from 'spectacle'; 16 | 17 | const Phase = props => ( 18 | 19 | 20 | {props.title} 21 | 22 |
23 | {props.children} 24 |
25 | ); 26 | 27 | export default Phase; 28 | -------------------------------------------------------------------------------- /phaseL/src/components/ClassDeclaration/ClassDeclaration.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component, ReactNode } from 'react'; 2 | import { Smart } from '../..'; 3 | 4 | export interface ClassDeclarationProps { 5 | children?: ReactNode; 6 | name: string; 7 | superClassName?: string; 8 | } 9 | 10 | export class ClassDeclaration extends Component { 11 | render() { 12 | const code = `class ${this.props.name} ${ 13 | this.props.superClassName ? `extends ${this.props.superClassName} ` : '' 14 | }{}`; 15 | return {this.props.children}; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /phaseL/src/components/InterfaceDeclaration/InterfaceDeclaration.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component, ReactNode } from 'react'; 2 | import { Smart } from '../..'; 3 | 4 | export interface InterfaceDeclarationProps { 5 | children?: ReactNode; 6 | extends?: string; 7 | name: string; 8 | } 9 | 10 | export class InterfaceDeclaration extends Component { 11 | render() { 12 | const code = `interface ${this.props.name} ${ 13 | this.props.extends ? `extends ${this.props.extends} ` : '' 14 | }{}`; 15 | return {this.props.children}; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /phaseA/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["src"] 21 | } 22 | -------------------------------------------------------------------------------- /phaseB/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["src"] 21 | } 22 | -------------------------------------------------------------------------------- /phaseC/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["src"] 21 | } 22 | -------------------------------------------------------------------------------- /phaseD/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["src"] 21 | } 22 | -------------------------------------------------------------------------------- /phaseE/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["src"] 21 | } 22 | -------------------------------------------------------------------------------- /phaseF/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["src"] 21 | } 22 | -------------------------------------------------------------------------------- /phaseG/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["src"] 21 | } 22 | -------------------------------------------------------------------------------- /phaseH/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["src"] 21 | } 22 | -------------------------------------------------------------------------------- /phaseI/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["src"] 21 | } 22 | -------------------------------------------------------------------------------- /phaseJ/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["src"] 21 | } 22 | -------------------------------------------------------------------------------- /phaseK/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["src"] 21 | } 22 | -------------------------------------------------------------------------------- /phaseL/src/components/ExportNamedDeclaration/ExportNamedDeclaration.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ClassDeclaration } from '../ClassDeclaration'; 3 | import { ExportNamedDeclaration } from './ExportNamedDeclaration'; 4 | import { render } from '../..'; 5 | 6 | describe('', () => { 7 | it('renders', () => { 8 | const code = render( 9 | 10 | 11 | , 12 | { prettier: false } 13 | ); 14 | expect(code).toBe('export class Button {}'); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /phaseL/src/components/InterfaceDeclaration/InterfaceDeclaration.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { InterfaceDeclaration } from './InterfaceDeclaration'; 3 | import { render } from '../..'; 4 | 5 | describe('', () => { 6 | it('renders', () => { 7 | const code = render( 8 | , 9 | { 10 | parserOptions: { 11 | plugins: ['typescript'] 12 | }, 13 | prettier: false 14 | } 15 | ); 16 | expect(code).toBe('interface Button extends Component {}'); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /phaseL/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["src"] 21 | } 22 | -------------------------------------------------------------------------------- /phaseA/example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "Node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["."] 21 | } 22 | -------------------------------------------------------------------------------- /phaseB/example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "Node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["."] 21 | } 22 | -------------------------------------------------------------------------------- /phaseC/example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "Node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["."] 21 | } 22 | -------------------------------------------------------------------------------- /phaseD/example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "Node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["."] 21 | } 22 | -------------------------------------------------------------------------------- /phaseE/example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "Node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["."] 21 | } 22 | -------------------------------------------------------------------------------- /phaseF/example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "Node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["."] 21 | } 22 | -------------------------------------------------------------------------------- /phaseG/example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "Node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["."] 21 | } 22 | -------------------------------------------------------------------------------- /phaseH/example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "Node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["."] 21 | } 22 | -------------------------------------------------------------------------------- /phaseI/example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "Node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["."] 21 | } 22 | -------------------------------------------------------------------------------- /phaseJ/example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "Node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["."] 21 | } 22 | -------------------------------------------------------------------------------- /phaseK/example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "Node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["."] 21 | } 22 | -------------------------------------------------------------------------------- /phaseL/example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "incremental": true, 9 | "jsx": "preserve", 10 | "lib": ["esnext"], 11 | "module": "commonjs", 12 | "moduleResolution": "Node", 13 | "outDir": "lib", 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "strictPropertyInitialization": false, 18 | "target": "esnext" 19 | }, 20 | "include": ["."] 21 | } 22 | -------------------------------------------------------------------------------- /phaseK/src/context.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import { TemplateBuilderOptions } from '@babel/template'; 3 | 4 | const _context: Context = { 5 | parserOptions: { 6 | placeholderPattern: false, 7 | placeholderWhitelist: new Set() 8 | } 9 | }; 10 | 11 | export interface Context { 12 | parserOptions: TemplateBuilderOptions; 13 | } 14 | 15 | export function updateContext(context: Context): Context { 16 | _.assign(_context, _.merge(_context, context)); 17 | return getContext(); 18 | } 19 | 20 | export function getContext(): Context { 21 | return _context; 22 | } 23 | 24 | export default getContext(); 25 | -------------------------------------------------------------------------------- /phaseL/src/components/ExportDefaultDeclaration/ExportDefaultDeclaration.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ClassDeclaration } from '../ClassDeclaration'; 3 | import { ExportDefaultDeclaration } from './ExportDefaultDeclaration'; 4 | import { render } from '../..'; 5 | 6 | describe('', () => { 7 | it('renders', () => { 8 | const code = render( 9 | 10 | 11 | , 12 | { prettier: false } 13 | ); 14 | expect(code).toBe('export default class C {}'); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /phaseL/src/context.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import { TemplateBuilderOptions } from '@babel/template'; 3 | 4 | const _context: Context = { 5 | parserOptions: { 6 | placeholderPattern: false, 7 | placeholderWhitelist: new Set() 8 | } 9 | }; 10 | 11 | export interface Context { 12 | parserOptions: TemplateBuilderOptions; 13 | } 14 | 15 | export function updateContext(context: Context): Context { 16 | _.assign(_context, _.merge(_context, context)); 17 | return getContext(); 18 | } 19 | 20 | export function getContext(): Context { 21 | return _context; 22 | } 23 | 24 | export default getContext(); 25 | -------------------------------------------------------------------------------- /phaseL/src/components/CallExpression/CallExpression.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component, ReactNode } from 'react'; 2 | import { Smart } from '../..'; 3 | 4 | export interface CallExpressionProps { 5 | name: string; 6 | arguments?: ReactNode | number | string; 7 | } 8 | 9 | export class CallExpression extends Component { 10 | renderArguments() { 11 | return this.props.arguments; 12 | } 13 | 14 | render() { 15 | const code = `${this.props.name}()`; 16 | return ( 17 | 18 | {this.renderArguments} 19 | 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /phaseA/README.md: -------------------------------------------------------------------------------- 1 | # Phase A 2 | 3 | > setup the reconciler 4 | 5 | ## Steps 6 | 7 | ### Create reconciler 8 | 9 | For now we will just log each of the lifecycle methods 10 | 11 | ### Create base element 12 | 13 | ### Create render function 14 | 15 | 1. initialize root element 16 | 2. initialize root fiber `reconciler.createContainer` 17 | 3. reconcile virtual dom `reconciler.updateContainer` 18 | 19 | ## Interesting Files 20 | 21 | [src/reconciler.ts](src/reconciler.ts) 22 | 23 | [src/render.ts](src/render.ts) 24 | 25 | [src/elements/BaseElement.ts](src/elements/BaseElement.ts) 26 | 27 | ## Demo 28 | 29 | ```sh 30 | npm run start 31 | ``` 32 | -------------------------------------------------------------------------------- /phaseA/src/elements/BaseElement.ts: -------------------------------------------------------------------------------- 1 | import { BaseNode, Node, Instance, Props } from '../types'; 2 | 3 | export default class BaseElement implements Instance { 4 | static defaultProps: Props = {}; 5 | 6 | static propTypes: object = {}; 7 | 8 | node: Node; 9 | 10 | props: Props; 11 | 12 | children: BaseElement[] = []; 13 | 14 | constructor(baseNode: BaseNode | BaseNode[], props: Props = {}) { 15 | this.node = baseNode; 16 | this.props = props; 17 | } 18 | 19 | appendChild(_child: BaseElement) {} 20 | 21 | removeChild(_child: BaseElement) {} 22 | 23 | commitMount() {} 24 | 25 | commitUpdate(_newProps: Props) {} 26 | } 27 | -------------------------------------------------------------------------------- /phaseD/README.md: -------------------------------------------------------------------------------- 1 | # Phase D 2 | 3 | > setup node 4 | 5 | From this point forward, everything is very specific to the react ast renderer, but the 6 | basic concepts remain the same. 7 | 8 | ## Steps 9 | 10 | ### Create node type 11 | 12 | ### Replace element used for root element 13 | 14 | The most critical element to get things working 15 | is the root element, since it is required to 16 | create the root fiber 17 | 18 | ## Interesting Files 19 | 20 | [src/types.ts](src/types.ts) 21 | 22 | [src/elements/BaseElement.ts](src/elements/BaseElement.ts) 23 | 24 | [src/elements/File.ts](src/elements/File.ts) 25 | 26 | ## Demo 27 | 28 | ```sh 29 | npm run start 30 | ``` 31 | -------------------------------------------------------------------------------- /slides/presentation/slides/Home.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | BlockQuote, 4 | Cite, 5 | Deck, 6 | Heading, 7 | Image, 8 | List, 9 | ListItem, 10 | Notes, 11 | Quote, 12 | Slide, 13 | Text 14 | } from 'spectacle'; 15 | 16 | const Home = () => ( 17 | 18 | 19 | Building a Custom 20 |
React Renderer 21 |
22 |
23 | 24 | github.com/codejamninja/create-react-renderer 25 | 26 |
27 | ); 28 | 29 | export default Home; 30 | -------------------------------------------------------------------------------- /phaseL/src/components/ReturnStatement/ReturnStatement.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ReturnStatement } from './ReturnStatement'; 3 | import { render, Literal } from '../..'; 4 | 5 | describe('', () => { 6 | it('renders', () => { 7 | const code = render(r, { 8 | prettier: false 9 | }); 10 | expect(code).toBe("return 'r';"); 11 | }); 12 | 13 | it('renders with react children', () => { 14 | const code = render( 15 | 16 | {[]} 17 | , 18 | { prettier: false } 19 | ); 20 | expect(code).toBe('return [];'); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /phaseD/src/render.ts: -------------------------------------------------------------------------------- 1 | import reconciler from './reconciler'; 2 | import { File } from './elements'; 3 | import { Options } from './types'; 4 | 5 | export function render(jsx: JSX.Element, _options: Options = {}) { 6 | // create root element 7 | // a root node is already injected by this element constructor 8 | const rootElement = new File(); 9 | 10 | // create root fiber 11 | const root = reconciler.createContainer(rootElement, false, false); 12 | 13 | // reconcile virtual dom 14 | reconciler.updateContainer(jsx, root, null, () => {}); 15 | 16 | // return rendered result (not required for side effect renderers) 17 | // in this case the rendered result is the node itself 18 | return rootElement.node; 19 | } 20 | -------------------------------------------------------------------------------- /phaseE/src/render.ts: -------------------------------------------------------------------------------- 1 | import reconciler from './reconciler'; 2 | import { File } from './elements'; 3 | import { Options } from './types'; 4 | 5 | export function render(jsx: JSX.Element, _options: Options = {}) { 6 | // create root element 7 | // a root node is already injected by this element constructor 8 | const rootElement = new File(); 9 | 10 | // create root fiber 11 | const root = reconciler.createContainer(rootElement, false, false); 12 | 13 | // reconcile virtual dom 14 | reconciler.updateContainer(jsx, root, null, () => {}); 15 | 16 | // return rendered result (not required for side effect renderers) 17 | // in this case the rendered result is the node itself 18 | return rootElement.node; 19 | } 20 | -------------------------------------------------------------------------------- /phaseF/src/render.ts: -------------------------------------------------------------------------------- 1 | import reconciler from './reconciler'; 2 | import { File } from './elements'; 3 | import { Options } from './types'; 4 | 5 | export function render(jsx: JSX.Element, _options: Options = {}) { 6 | // create root element 7 | // a root node is already injected by this element constructor 8 | const rootElement = new File(); 9 | 10 | // create root fiber 11 | const root = reconciler.createContainer(rootElement, false, false); 12 | 13 | // reconcile virtual dom 14 | reconciler.updateContainer(jsx, root, null, () => {}); 15 | 16 | // return rendered result (not required for side effect renderers) 17 | // in this case the rendered result is the node itself 18 | return rootElement.node; 19 | } 20 | -------------------------------------------------------------------------------- /phaseG/src/render.ts: -------------------------------------------------------------------------------- 1 | import reconciler from './reconciler'; 2 | import { File } from './elements'; 3 | import { Options } from './types'; 4 | 5 | export function render(jsx: JSX.Element, _options: Options = {}) { 6 | // create root element 7 | // a root node is already injected by this element constructor 8 | const rootElement = new File(); 9 | 10 | // create root fiber 11 | const root = reconciler.createContainer(rootElement, false, false); 12 | 13 | // reconcile virtual dom 14 | reconciler.updateContainer(jsx, root, null, () => {}); 15 | 16 | // return rendered result (not required for side effect renderers) 17 | // in this case the rendered result is the node itself 18 | return rootElement.node; 19 | } 20 | -------------------------------------------------------------------------------- /phaseH/src/render.ts: -------------------------------------------------------------------------------- 1 | import reconciler from './reconciler'; 2 | import { File } from './elements'; 3 | import { Options } from './types'; 4 | 5 | export function render(jsx: JSX.Element, _options: Options = {}) { 6 | // create root element 7 | // a root node is already injected by this element constructor 8 | const rootElement = new File(); 9 | 10 | // create root fiber 11 | const root = reconciler.createContainer(rootElement, false, false); 12 | 13 | // reconcile virtual dom 14 | reconciler.updateContainer(jsx, root, null, () => {}); 15 | 16 | // return rendered result (not required for side effect renderers) 17 | // in this case the rendered result is the node itself 18 | return rootElement.node; 19 | } 20 | -------------------------------------------------------------------------------- /phaseI/src/render.ts: -------------------------------------------------------------------------------- 1 | import reconciler from './reconciler'; 2 | import { File } from './elements'; 3 | import { Options } from './types'; 4 | 5 | export function render(jsx: JSX.Element, _options: Options = {}) { 6 | // create root element 7 | // a root node is already injected by this element constructor 8 | const rootElement = new File(); 9 | 10 | // create root fiber 11 | const root = reconciler.createContainer(rootElement, false, false); 12 | 13 | // reconcile virtual dom 14 | reconciler.updateContainer(jsx, root, null, () => {}); 15 | 16 | // return rendered result (not required for side effect renderers) 17 | // in this case the rendered result is the node itself 18 | return rootElement.node; 19 | } 20 | -------------------------------------------------------------------------------- /phaseJ/src/render.ts: -------------------------------------------------------------------------------- 1 | import reconciler from './reconciler'; 2 | import { File } from './elements'; 3 | import { Options } from './types'; 4 | 5 | export function render(jsx: JSX.Element, _options: Options = {}) { 6 | // create root element 7 | // a root node is already injected by this element constructor 8 | const rootElement = new File(); 9 | 10 | // create root fiber 11 | const root = reconciler.createContainer(rootElement, false, false); 12 | 13 | // reconcile virtual dom 14 | reconciler.updateContainer(jsx, root, null, () => {}); 15 | 16 | // return rendered result (not required for side effect renderers) 17 | // in this case the rendered result is the node itself 18 | return rootElement.node; 19 | } 20 | -------------------------------------------------------------------------------- /phaseB/src/render.ts: -------------------------------------------------------------------------------- 1 | import reconciler from './reconciler'; 2 | import { Wrapper } from './elements'; 3 | import { Options } from './types'; 4 | 5 | export function render(jsx: JSX.Element, _options: Options = {}) { 6 | // create root element 7 | // a root node is already injected by this element constructor 8 | const rootElement = new Wrapper(); 9 | 10 | // create root fiber 11 | const root = reconciler.createContainer(rootElement, false, false); 12 | 13 | // reconcile virtual dom 14 | reconciler.updateContainer(jsx, root, null, () => {}); 15 | 16 | // return rendered result (not required for side effect renderers) 17 | // in this case the rendered result is the node itself 18 | return rootElement.node; 19 | } 20 | -------------------------------------------------------------------------------- /phaseC/src/render.ts: -------------------------------------------------------------------------------- 1 | import reconciler from './reconciler'; 2 | import { Wrapper } from './elements'; 3 | import { Options } from './types'; 4 | 5 | export function render(jsx: JSX.Element, _options: Options = {}) { 6 | // create root element 7 | // a root node is already injected by this element constructor 8 | const rootElement = new Wrapper(); 9 | 10 | // create root fiber 11 | const root = reconciler.createContainer(rootElement, false, false); 12 | 13 | // reconcile virtual dom 14 | reconciler.updateContainer(jsx, root, null, () => {}); 15 | 16 | // return rendered result (not required for side effect renderers) 17 | // in this case the rendered result is the node itself 18 | return rootElement.node; 19 | } 20 | -------------------------------------------------------------------------------- /slides/presentation/slides/Definition.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | BlockQuote, 4 | Markdown, 5 | Cite, 6 | Deck, 7 | Heading, 8 | Image, 9 | List, 10 | ListItem, 11 | Notes, 12 | Quote, 13 | Slide, 14 | Text 15 | } from 'spectacle'; 16 | 17 | const Definition = props => ( 18 | 19 |
20 | 26 | {props.title} 27 | 28 |
29 | {props.children} 30 |
31 | ); 32 | 33 | export default Definition; 34 | -------------------------------------------------------------------------------- /phaseL/src/components/ImportDeclaration/ImportDeclaration.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ImportDeclaration } from './ImportDeclaration'; 3 | import { render } from '../..'; 4 | 5 | describe('', () => { 6 | it('imports default export', () => { 7 | const code = render( 8 | , 9 | { prettier: false } 10 | ); 11 | expect(code).toBe("import hello from 'world';"); 12 | }); 13 | 14 | it('renders', () => { 15 | const code = render( 16 | , 17 | { prettier: false } 18 | ); 19 | expect(code).toBe("import { one, two } from 'world';"); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /phaseL/src/components/FunctionExpression/FunctionExpression.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { FunctionExpression } from './FunctionExpression'; 3 | import { render } from '../..'; 4 | 5 | describe('', () => { 6 | it('renders', () => { 7 | const code = render(, { 8 | prettier: false 9 | }); 10 | expect(code).toBe('function () {}'); 11 | }); 12 | }); 13 | 14 | describe('', () => { 15 | it('renders', () => { 16 | const code = render(, { 17 | prettier: false, 18 | parserOptions: { 19 | plugins: ['typescript'] 20 | } 21 | }); 22 | expect(code).toBe('function (): any {}'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /phaseB/src/elements/BaseElement.ts: -------------------------------------------------------------------------------- 1 | import { BaseNode, Node, Instance, Props } from '../types'; 2 | 3 | export interface IElement { 4 | new (props?: Props): BaseElement; 5 | propTypes: object; 6 | defaultProps: Props; 7 | } 8 | 9 | export default class BaseElement implements Instance { 10 | static defaultProps: Props = {}; 11 | 12 | static propTypes: object = {}; 13 | 14 | node: Node; 15 | 16 | props: Props; 17 | 18 | children: BaseElement[] = []; 19 | 20 | constructor(baseNode: BaseNode | BaseNode[], props: Props = {}) { 21 | this.node = baseNode; 22 | this.props = props; 23 | } 24 | 25 | appendChild(_child: BaseElement) {} 26 | 27 | removeChild(_child: BaseElement) {} 28 | 29 | commitMount() {} 30 | 31 | commitUpdate(_newProps: Props) {} 32 | } 33 | -------------------------------------------------------------------------------- /phaseC/src/elements/BaseElement.ts: -------------------------------------------------------------------------------- 1 | import { BaseNode, Node, Instance, Props } from '../types'; 2 | 3 | export interface IElement { 4 | new (props?: Props): BaseElement; 5 | propTypes: object; 6 | defaultProps: Props; 7 | } 8 | 9 | export default class BaseElement implements Instance { 10 | static defaultProps: Props = {}; 11 | 12 | static propTypes: object = {}; 13 | 14 | node: Node; 15 | 16 | props: Props; 17 | 18 | children: BaseElement[] = []; 19 | 20 | constructor(baseNode: BaseNode | BaseNode[], props: Props = {}) { 21 | this.node = baseNode; 22 | this.props = props; 23 | } 24 | 25 | appendChild(_child: BaseElement) {} 26 | 27 | removeChild(_child: BaseElement) {} 28 | 29 | commitMount() {} 30 | 31 | commitUpdate(_newProps: Props) {} 32 | } 33 | -------------------------------------------------------------------------------- /phaseL/src/components/ImportDeclaration/ImportDeclaration.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { oc } from 'ts-optchain.macro'; 3 | import { Smart } from '../..'; 4 | 5 | export interface ImportDeclarationProps { 6 | defaultExport?: string; 7 | exports?: string[]; 8 | source: string; 9 | } 10 | 11 | export class ImportDeclaration extends Component { 12 | render() { 13 | const exports = oc(this.props).exports([]); 14 | const code = `import ${ 15 | this.props.defaultExport 16 | ? `${this.props.defaultExport}${exports.length ? ',' : ''} ` 17 | : '' 18 | }${exports.length ? `{${exports.join(',')}} ` : ''}from '${ 19 | this.props.source 20 | }'`; 21 | return ; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /phaseL/src/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ArrowFunctionExpression'; 2 | export * from './CallExpression'; 3 | export * from './ClassDeclaration'; 4 | export * from './ClassMethod'; 5 | export * from './ClassProperty'; 6 | export * from './Code'; 7 | export * from './ExportDefaultDeclaration'; 8 | export * from './ExportNamedDeclaration'; 9 | export * from './FunctionDeclaration'; 10 | export * from './FunctionExpression'; 11 | export * from './ImportDeclaration'; 12 | export * from './InterfaceDeclaration'; 13 | export * from './JsxElement'; 14 | export * from './Literal'; 15 | export * from './MethodSignature'; 16 | export * from './Param'; 17 | export * from './ReturnStatement'; 18 | export * from './TypeAnnotation'; 19 | export * from './TypeParam'; 20 | export * from './VariableDeclaration'; 21 | -------------------------------------------------------------------------------- /slides/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env", 4 | "@babel/preset-react" 5 | ], 6 | "plugins": [ 7 | "react-hot-loader/babel", 8 | ["@babel/plugin-proposal-decorators", { "legacy": true }] 9 | ], 10 | "env": { 11 | "production": { 12 | "plugins": [ 13 | ["@babel/plugin-transform-modules-commonjs"], 14 | "transform-react-remove-prop-types", 15 | "@babel/plugin-transform-react-constant-elements", 16 | "@babel/plugin-transform-react-inline-elements", 17 | "@babel/plugin-transform-runtime", 18 | ["@babel/plugin-proposal-decorators", { "legacy": true }] 19 | ] 20 | }, 21 | "test": { 22 | "plugins": [ 23 | "@babel/plugin-transform-modules-commonjs" 24 | ] 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /phaseL/src/components/ArrowFunctionExpression/ArrowFunctionExpression.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ArrowFunctionExpression } from './ArrowFunctionExpression'; 3 | import { render } from '../..'; 4 | 5 | describe('', () => { 6 | it('renders', () => { 7 | const code = render(, { 8 | prettier: false 9 | }); 10 | expect(code).toBe('() => {}'); 11 | }); 12 | }); 13 | 14 | describe('', () => { 15 | it('renders', () => { 16 | const code = render(, { 17 | prettier: false, 18 | parserOptions: { 19 | plugins: ['typescript'] 20 | } 21 | }); 22 | expect(code).toBe('(): any => {}'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /slides/server.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | var path = require("path"); 4 | var express = require("express"); 5 | var webpack = require("webpack"); 6 | var config = require("./webpack.config"); 7 | 8 | var app = express(); 9 | var compiler = webpack(config); 10 | 11 | var serverPort = process.env.PORT || 3000; 12 | 13 | app.use(require("webpack-dev-middleware")(compiler, { 14 | publicPath: config.output.publicPath 15 | })); 16 | 17 | app.use(require("webpack-hot-middleware")(compiler)); 18 | 19 | app.get("*", function(req, res) { 20 | res.sendFile(path.join(__dirname, "index.html")); 21 | }); 22 | 23 | app.listen(serverPort, "localhost", function (err) { 24 | if (err) { 25 | console.log(err); 26 | return; 27 | } 28 | 29 | console.log("Listening at http://localhost:" + serverPort); 30 | }); 31 | -------------------------------------------------------------------------------- /phaseL/src/components/PropertySignature/PropertySignature.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component, ReactNode } from 'react'; 2 | import { Smart, TypeAnnotation } from '../..'; 3 | 4 | export interface PropertySignatureProps { 5 | name: string; 6 | type?: ReactNode; 7 | } 8 | 9 | export class PropertySignature extends Component { 10 | renderTypeAnnotation() { 11 | return typeof this.props.type === 'string' ? ( 12 | {this.props.type} 13 | ) : ( 14 | this.props.type 15 | ); 16 | } 17 | 18 | render() { 19 | const code = `interface I {${this.props.name}: any}`; 20 | return ( 21 | 22 | {this.renderTypeAnnotation()} 23 | 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /phaseC/README.md: -------------------------------------------------------------------------------- 1 | # Phase C 2 | 3 | > bind some custom elements to reconciler 4 | 5 | ## Steps 6 | 7 | ### Fill out critical reconciler lifecycle methods 8 | 9 | #### createInstance 10 | 11 | ```ts 12 | createInstance( 13 | type: Type, 14 | props: Props, 15 | _rootContainerInstance: Container, 16 | _hostContext: HostContext 17 | ): Instance { 18 | return createElement(type, props); 19 | } 20 | ``` 21 | 22 | #### appendChildToContainer 23 | 24 | ```ts 25 | appendChildToContainer( 26 | container: Container, 27 | child: Instance | TextInstance 28 | ): void { 29 | container.appendChild(child); 30 | } 31 | ``` 32 | 33 | ## Interesting Files 34 | 35 | [src/reconciler.ts](src/reconciler.ts) 36 | 37 | [src/elements/Wrapper.ts](src/elements/Wrapper.ts) 38 | 39 | ## Demo 40 | 41 | ```sh 42 | npm run start 43 | ``` 44 | -------------------------------------------------------------------------------- /slides/presentation/slides/Tips.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | BlockQuote, 4 | Markdown, 5 | Cite, 6 | Deck, 7 | Heading, 8 | Image, 9 | List, 10 | ListItem, 11 | Notes, 12 | Quote, 13 | Slide, 14 | Text 15 | } from 'spectacle'; 16 | 17 | const Tips = props => ( 18 | 19 |
20 | 26 | {props.title} 27 | 28 |
29 | {props.children || ''} 30 |
31 | {props.image && props.image.length ? : null} 32 |
33 | ); 34 | 35 | export default Tips; 36 | -------------------------------------------------------------------------------- /slides/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | Build React Renderer 11 | 12 | 17 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /phaseJ/example/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from 'react'; 2 | import util from 'util'; 3 | import { render } from '../src'; 4 | 5 | export interface AppProps { 6 | hello?: string; 7 | howdy?: string; 8 | } 9 | 10 | export const App: FC = (props: AppProps) => { 11 | console.log('PROPS', props); 12 | return ( 13 | <> 14 | {props.hello} 15 | {props.howdy} 16 | 17 | ); 18 | }; 19 | App.defaultProps = { 20 | hello: "const hello = 'austin'", 21 | howdy: "const howdy = () => 'austin'" 22 | }; 23 | 24 | console.log('======== RECONCILER LIFECYCLE ========'); 25 | const renderedOutput = render(); 26 | 27 | console.log('\n\n======== RENDERED OUTPUT ========'); 28 | console.log(util.inspect(renderedOutput, false, null, true)); 29 | console.log('\n\n--------------'); 30 | -------------------------------------------------------------------------------- /phaseL/src/components/PropertySignature/PropertySignature.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { PropertySignature } from './PropertySignature'; 3 | import { render } from '../..'; 4 | 5 | describe('', () => { 6 | it('renders', () => { 7 | const code = render(, { 8 | parserOptions: { plugins: ['classProperties', 'typescript'] }, 9 | prettier: false 10 | }); 11 | expect(code).toBe('hello: any;'); 12 | }); 13 | }); 14 | 15 | describe('', () => { 16 | it('renders', () => { 17 | const code = render(, { 18 | parserOptions: { plugins: ['classProperties', 'typescript'] }, 19 | prettier: false 20 | }); 21 | expect(code).toBe('hello: string;'); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /phaseL/src/components/FunctionDeclaration/FunctionDeclaration.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { FunctionDeclaration } from './FunctionDeclaration'; 3 | import { render } from '../..'; 4 | 5 | describe('', () => { 6 | it('renders', () => { 7 | const code = render(, { 8 | prettier: false 9 | }); 10 | expect(code).toBe('function hello() {}'); 11 | }); 12 | }); 13 | 14 | describe('', () => { 15 | it('renders', () => { 16 | const code = render( 17 | , 18 | { 19 | prettier: false, 20 | parserOptions: { 21 | plugins: ['typescript'] 22 | } 23 | } 24 | ); 25 | expect(code).toBe('function hello(): string {}'); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /phaseL/src/components/Literal/Literal.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component, ReactNode } from 'react'; 2 | import { Smart } from '../..'; 3 | 4 | export interface LiteralProps { 5 | children: ReactNode | number | string; 6 | } 7 | 8 | export class Literal extends Component { 9 | render() { 10 | if (typeof this.props.children === 'string') { 11 | const code = `'${this.props.children}'`; 12 | return ; 13 | } 14 | if ( 15 | typeof this.props.children === 'number' || 16 | typeof this.props.children === 'boolean' 17 | ) { 18 | return ( 19 | 20 | ); 21 | } 22 | const code = `(${JSON.stringify(this.props.children)})`; 23 | return ; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /phaseL/src/components/Param/Param.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component, ReactNode } from 'react'; 2 | import { Smart, TypeAnnotation } from '../..'; 3 | 4 | export interface ParamProps { 5 | children: string; 6 | type?: ReactNode; 7 | signature?: boolean; 8 | } 9 | 10 | export class Param extends Component { 11 | renderTypeAnnotations() { 12 | return typeof this.props.type === 'string' ? ( 13 | {this.props.type} 14 | ) : ( 15 | this.props.type 16 | ); 17 | } 18 | 19 | render() { 20 | const code = `function f(${this.props.children}) {}`; 21 | return ( 22 | 27 | {this.renderTypeAnnotations()} 28 | 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /phaseK/README.md: -------------------------------------------------------------------------------- 1 | # Phase K 2 | 3 | > add options 4 | 5 | ## Steps 6 | 7 | ### Setup types for options 8 | 9 | ### Setup context to pass around options 10 | 11 | This is not required in all react renderers and some react renders use other 12 | strategies to pass around options 13 | 14 | ### Add dev tools support 15 | 16 | This can be accomplished by adding the following in the render function 17 | 18 | ```ts 19 | reconciler.injectIntoDevTools({ 20 | bundleType: Number(dev) as BundleType, 21 | rendererPackageName: pkg.name, 22 | version: pkg.version 23 | }); 24 | ``` 25 | 26 | ## Interesting Files 27 | 28 | [src/elements/BaseElement.ts](src/elements/BaseElement.ts) 29 | 30 | [src/context.ts](src/context.ts) 31 | 32 | [src/dev.ts](src/dev.ts) 33 | 34 | [src/render.ts](src/render.ts) 35 | 36 | [src/types.ts](src/types.ts) 37 | 38 | ## Usage 39 | 40 | ```sh 41 | npm run start 42 | ``` 43 | -------------------------------------------------------------------------------- /slides/assets/deck.example: -------------------------------------------------------------------------------- 1 | return ( 2 | 3 | 4 | 5 | React Presentations 6 | 7 | 8 | Written In React 9 | 10 | 11 | 12 | 13 | Wait What? 14 | 15 | 16 | 17 | 18 | Thats right 19 | 20 | 21 | Inline style based theme system 22 | Autofit Text 23 | PDF Export 24 | 25 | 26 | 27 | ) 28 | -------------------------------------------------------------------------------- /phaseD/src/elements/BaseElement.ts: -------------------------------------------------------------------------------- 1 | import { ParserOptions } from '@babel/parser'; 2 | import { BaseNode, Node, Instance, Props } from '../types'; 3 | 4 | export interface IElement { 5 | new (props?: Props, parserOptions?: ParserOptions): BaseElement; 6 | propTypes: object; 7 | defaultProps: Props; 8 | } 9 | 10 | export default class BaseElement implements Instance { 11 | static defaultProps: Props = {}; 12 | 13 | static propTypes: object = {}; 14 | 15 | node: Node; 16 | 17 | props: Props; 18 | 19 | children: BaseElement[] = []; 20 | 21 | constructor(baseNode: BaseNode | BaseNode[], _props: Props = {}) { 22 | if (Array.isArray(baseNode)) throw new Error('cannot be array'); 23 | this.node = baseNode; 24 | } 25 | 26 | appendChild(_child: BaseElement) {} 27 | 28 | removeChild(_child: BaseElement) {} 29 | 30 | commitMount() {} 31 | 32 | commitUpdate(_newProps: Props) {} 33 | } 34 | -------------------------------------------------------------------------------- /phaseG/src/@types/reactAst.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace JSX { 2 | // @ts-ignore 3 | import { ReactNode, Ref } from 'react'; 4 | import template, { 5 | TemplateBuilderOptions, 6 | PublicReplacements 7 | // @ts-ignore 8 | } from '@babel/template'; 9 | // @ts-ignore 10 | import { Path } from '..'; 11 | 12 | interface IntrinsicElements { 13 | Ast: { 14 | ref?: Ref; 15 | }; 16 | Expression: { 17 | ref?: Ref; 18 | }; 19 | File: { 20 | ref?: Ref; 21 | children?: ReactNode; 22 | }; 23 | Program: { 24 | ref?: Ref; 25 | }; 26 | Smart: { 27 | bodyPath?: Path; 28 | children?: ReactNode; 29 | code: string; 30 | options?: TemplateBuilderOptions; 31 | parentBodyPath?: Path; 32 | ref?: Ref; 33 | replacements?: PublicReplacements; 34 | scopePath?: Path; 35 | }; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /phaseH/src/@types/reactAst.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace JSX { 2 | // @ts-ignore 3 | import { ReactNode, Ref } from 'react'; 4 | import template, { 5 | TemplateBuilderOptions, 6 | PublicReplacements 7 | // @ts-ignore 8 | } from '@babel/template'; 9 | // @ts-ignore 10 | import { Path } from '..'; 11 | 12 | interface IntrinsicElements { 13 | Ast: { 14 | ref?: Ref; 15 | }; 16 | Expression: { 17 | ref?: Ref; 18 | }; 19 | File: { 20 | ref?: Ref; 21 | children?: ReactNode; 22 | }; 23 | Program: { 24 | ref?: Ref; 25 | }; 26 | Smart: { 27 | bodyPath?: Path; 28 | children?: ReactNode; 29 | code: string; 30 | options?: TemplateBuilderOptions; 31 | parentBodyPath?: Path; 32 | ref?: Ref; 33 | replacements?: PublicReplacements; 34 | scopePath?: Path; 35 | }; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /phaseI/src/@types/reactAst.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace JSX { 2 | // @ts-ignore 3 | import { ReactNode, Ref } from 'react'; 4 | import template, { 5 | TemplateBuilderOptions, 6 | PublicReplacements 7 | // @ts-ignore 8 | } from '@babel/template'; 9 | // @ts-ignore 10 | import { Path } from '..'; 11 | 12 | interface IntrinsicElements { 13 | Ast: { 14 | ref?: Ref; 15 | }; 16 | Expression: { 17 | ref?: Ref; 18 | }; 19 | File: { 20 | ref?: Ref; 21 | children?: ReactNode; 22 | }; 23 | Program: { 24 | ref?: Ref; 25 | }; 26 | Smart: { 27 | bodyPath?: Path; 28 | children?: ReactNode; 29 | code: string; 30 | options?: TemplateBuilderOptions; 31 | parentBodyPath?: Path; 32 | ref?: Ref; 33 | replacements?: PublicReplacements; 34 | scopePath?: Path; 35 | }; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /phaseJ/src/@types/reactAst.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace JSX { 2 | // @ts-ignore 3 | import { ReactNode, Ref } from 'react'; 4 | import template, { 5 | TemplateBuilderOptions, 6 | PublicReplacements 7 | // @ts-ignore 8 | } from '@babel/template'; 9 | // @ts-ignore 10 | import { Path } from '..'; 11 | 12 | interface IntrinsicElements { 13 | Ast: { 14 | ref?: Ref; 15 | }; 16 | Expression: { 17 | ref?: Ref; 18 | }; 19 | File: { 20 | ref?: Ref; 21 | children?: ReactNode; 22 | }; 23 | Program: { 24 | ref?: Ref; 25 | }; 26 | Smart: { 27 | bodyPath?: Path; 28 | children?: ReactNode; 29 | code: string; 30 | options?: TemplateBuilderOptions; 31 | parentBodyPath?: Path; 32 | ref?: Ref; 33 | replacements?: PublicReplacements; 34 | scopePath?: Path; 35 | }; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /phaseK/src/@types/reactAst.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace JSX { 2 | // @ts-ignore 3 | import { ReactNode, Ref } from 'react'; 4 | import template, { 5 | TemplateBuilderOptions, 6 | PublicReplacements 7 | // @ts-ignore 8 | } from '@babel/template'; 9 | // @ts-ignore 10 | import { Path } from '..'; 11 | 12 | interface IntrinsicElements { 13 | Ast: { 14 | ref?: Ref; 15 | }; 16 | Expression: { 17 | ref?: Ref; 18 | }; 19 | File: { 20 | ref?: Ref; 21 | children?: ReactNode; 22 | }; 23 | Program: { 24 | ref?: Ref; 25 | }; 26 | Smart: { 27 | bodyPath?: Path; 28 | children?: ReactNode; 29 | code: string; 30 | options?: TemplateBuilderOptions; 31 | parentBodyPath?: Path; 32 | ref?: Ref; 33 | replacements?: PublicReplacements; 34 | scopePath?: Path; 35 | }; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /phaseL/src/@types/reactAst.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace JSX { 2 | // @ts-ignore 3 | import { ReactNode, Ref } from 'react'; 4 | import template, { 5 | TemplateBuilderOptions, 6 | PublicReplacements 7 | // @ts-ignore 8 | } from '@babel/template'; 9 | // @ts-ignore 10 | import { Path } from '..'; 11 | 12 | interface IntrinsicElements { 13 | Ast: { 14 | ref?: Ref; 15 | }; 16 | Expression: { 17 | ref?: Ref; 18 | }; 19 | File: { 20 | ref?: Ref; 21 | children?: ReactNode; 22 | }; 23 | Program: { 24 | ref?: Ref; 25 | }; 26 | Smart: { 27 | bodyPath?: Path; 28 | children?: ReactNode; 29 | code: string; 30 | options?: TemplateBuilderOptions; 31 | parentBodyPath?: Path; 32 | ref?: Ref; 33 | replacements?: PublicReplacements; 34 | scopePath?: Path; 35 | }; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /phaseL/src/components/VariableDeclaration/VariableDeclaration.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { VariableDeclaration } from './VariableDeclaration'; 3 | import { render } from '../..'; 4 | 5 | describe('', () => { 6 | it('renders', () => { 7 | const code = render( 8 | world, 9 | { prettier: false } 10 | ); 11 | expect(code).toBe("var hello = 'world';"); 12 | }); 13 | }); 14 | 15 | describe('', () => { 16 | it('renders', () => { 17 | const code = render( 18 | 19 | world 20 | , 21 | { 22 | parserOptions: { plugins: ['typescript'] }, 23 | prettier: false 24 | } 25 | ); 26 | expect(code).toBe("var hello: string = 'world';"); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /slides/presentation/slides/Diagram.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | BlockQuote, 4 | Markdown, 5 | Cite, 6 | Deck, 7 | Heading, 8 | Image, 9 | List, 10 | ListItem, 11 | Notes, 12 | Quote, 13 | Slide, 14 | Text 15 | } from 'spectacle'; 16 | import diagram from '../../assets/react-renderer-binding-diagram.jpg'; 17 | 18 | const Diagram = props => ( 19 | 20 |
21 | 26 | React Renderer Bindings Diagram 27 | 28 |
29 | 30 | {` 31 |
32 |
40 | 41 | ) : ( 42 | 43 | Easy there pal 44 | 45 | )} 46 | 47 | ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /phaseF/README.md: -------------------------------------------------------------------------------- 1 | # Phase F 2 | 3 | > bind critical element lifecycle methods to reconciler lifecycle methods 4 | 5 | ## Steps 6 | 7 | ### Fill out critical lifecycle methods 8 | 9 | The critical lifecycle methods involve creating and appending elements 10 | 11 | #### createInstance 12 | 13 | Already done in [phaseC](../phaseC) 14 | 15 | ```ts 16 | createInstance( 17 | type: Type, 18 | props: Props, 19 | _rootContainerInstance: Container, 20 | _hostContext: HostContext 21 | ): Instance { 22 | return createElement(type, props); 23 | } 24 | ``` 25 | 26 | #### appendChild 27 | 28 | ```ts 29 | appendChild(parentInstance: Instance, child: Instance | TextInstance): void { 30 | parentInstance.appendChild(child); 31 | } 32 | ``` 33 | 34 | #### appendChildToContainer 35 | 36 | Already done in [phaseC](../phaseC) 37 | 38 | ```ts 39 | appendChildToContainer( 40 | container: Container, 41 | child: Instance | TextInstance 42 | ): void { 43 | container.appendChild(child); 44 | } 45 | ``` 46 | 47 | #### appendInitialChild 48 | 49 | ```ts 50 | appendInitialChild( 51 | parentInstance: Instance, 52 | child: Instance | TextInstance 53 | ): void { 54 | log.debug('appendInitialChild'); 55 | parentInstance.appendChild(child); 56 | } 57 | ``` 58 | 59 | ## Interesting Files 60 | 61 | [src/reconciler.ts](src/reconciler.ts) 62 | 63 | ## Demo 64 | 65 | ```sh 66 | npm run start 67 | ``` 68 | -------------------------------------------------------------------------------- /phaseA/src/types.ts: -------------------------------------------------------------------------------- 1 | export interface BaseNode { 2 | [key: string]: any; 3 | } 4 | 5 | export interface Options { 6 | [key: string]: any; 7 | } 8 | 9 | export type BundleType = 0 | 1; 10 | 11 | export type Type = string; 12 | 13 | export type Prop = any; 14 | 15 | export type ContextItem = any; 16 | 17 | export type HydratableInstance = any; 18 | 19 | export type PublicInstance = Instance | TextInstance; 20 | 21 | export type HostContext = Context; 22 | 23 | export type UpdatePayload = any; 24 | 25 | export type ChildSet = any; 26 | 27 | export type TimeoutHandle = any; 28 | 29 | export type NoTimeout = any; 30 | 31 | export interface Container extends Instance {} 32 | 33 | export interface TextInstance extends Instance {} 34 | 35 | export interface DeepArray extends Array> {} 36 | 37 | export interface Props { 38 | [key: string]: Prop; 39 | } 40 | 41 | export interface Instance { 42 | appendChild(child: Instance | TextInstance): void; 43 | children: Instance[]; 44 | commitMount(): void; 45 | commitUpdate(newProps: Props): void; 46 | node: Node; 47 | props: Props; 48 | removeChild(child: Instance | TextInstance): void; 49 | } 50 | 51 | export interface Pkg { 52 | [key: string]: any; 53 | } 54 | 55 | export interface Context { 56 | [key: string]: ContextItem; 57 | } 58 | 59 | export interface Node extends BaseNode { 60 | body?: BaseNode[]; 61 | } 62 | -------------------------------------------------------------------------------- /phaseB/src/types.ts: -------------------------------------------------------------------------------- 1 | export interface BaseNode { 2 | [key: string]: any; 3 | } 4 | 5 | export interface Options { 6 | [key: string]: any; 7 | } 8 | 9 | export type BundleType = 0 | 1; 10 | 11 | export type Type = string; 12 | 13 | export type Prop = any; 14 | 15 | export type ContextItem = any; 16 | 17 | export type HydratableInstance = any; 18 | 19 | export type PublicInstance = Instance | TextInstance; 20 | 21 | export type HostContext = Context; 22 | 23 | export type UpdatePayload = any; 24 | 25 | export type ChildSet = any; 26 | 27 | export type TimeoutHandle = any; 28 | 29 | export type NoTimeout = any; 30 | 31 | export interface Container extends Instance {} 32 | 33 | export interface TextInstance extends Instance {} 34 | 35 | export interface DeepArray extends Array> {} 36 | 37 | export interface Props { 38 | [key: string]: Prop; 39 | } 40 | 41 | export interface Instance { 42 | appendChild(child: Instance | TextInstance): void; 43 | children: Instance[]; 44 | commitMount(): void; 45 | commitUpdate(newProps: Props): void; 46 | node: Node; 47 | props: Props; 48 | removeChild(child: Instance | TextInstance): void; 49 | } 50 | 51 | export interface Pkg { 52 | [key: string]: any; 53 | } 54 | 55 | export interface Context { 56 | [key: string]: ContextItem; 57 | } 58 | 59 | export interface Node extends BaseNode { 60 | body?: BaseNode[]; 61 | } 62 | -------------------------------------------------------------------------------- /phaseC/src/types.ts: -------------------------------------------------------------------------------- 1 | export interface BaseNode { 2 | [key: string]: any; 3 | } 4 | 5 | export interface Options { 6 | [key: string]: any; 7 | } 8 | 9 | export type BundleType = 0 | 1; 10 | 11 | export type Type = string; 12 | 13 | export type Prop = any; 14 | 15 | export type ContextItem = any; 16 | 17 | export type HydratableInstance = any; 18 | 19 | export type PublicInstance = Instance | TextInstance; 20 | 21 | export type HostContext = Context; 22 | 23 | export type UpdatePayload = any; 24 | 25 | export type ChildSet = any; 26 | 27 | export type TimeoutHandle = any; 28 | 29 | export type NoTimeout = any; 30 | 31 | export interface Container extends Instance {} 32 | 33 | export interface TextInstance extends Instance {} 34 | 35 | export interface DeepArray extends Array> {} 36 | 37 | export interface Props { 38 | [key: string]: Prop; 39 | } 40 | 41 | export interface Instance { 42 | appendChild(child: Instance | TextInstance): void; 43 | children: Instance[]; 44 | commitMount(): void; 45 | commitUpdate(newProps: Props): void; 46 | node: Node; 47 | props: Props; 48 | removeChild(child: Instance | TextInstance): void; 49 | } 50 | 51 | export interface Pkg { 52 | [key: string]: any; 53 | } 54 | 55 | export interface Context { 56 | [key: string]: ContextItem; 57 | } 58 | 59 | export interface Node extends BaseNode { 60 | body?: BaseNode[]; 61 | } 62 | -------------------------------------------------------------------------------- /phaseL/src/components/JsxAttribute/JsxAttribute.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component, ReactNode } from 'react'; 2 | import { Smart } from '../..'; 3 | 4 | export interface JsxAttributeProps { 5 | name: string; 6 | children?: ReactNode | string | number; 7 | } 8 | 9 | export class JsxAttribute extends Component { 10 | render() { 11 | let code = ''; 12 | if (typeof this.props.children === 'string') { 13 | code = ``; 14 | } else if (typeof this.props.children === 'number') { 15 | code = ``; 16 | } else if (typeof this.props.children === 'boolean') { 17 | if (this.props.children) { 18 | code = ``; 19 | } else { 20 | code = ``; 21 | } 22 | } 23 | if (code.length) { 24 | return ( 25 | 30 | ); 31 | } 32 | code = ``; 33 | return ( 34 | 40 | {this.props.children} 41 | 42 | ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /phaseL/example/ReactFunctionalComponent.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC, ReactNode } from 'react'; 2 | import { 3 | ArrowFunctionExpression, 4 | Code, 5 | ExportDefaultDeclaration, 6 | ImportDeclaration, 7 | InterfaceDeclaration, 8 | MethodSignature, 9 | Param, 10 | TypeAnnotation, 11 | VariableDeclaration 12 | } from '../src'; 13 | 14 | export interface ReactFunctionalComponentProps { 15 | name: string; 16 | children?: ReactNode; 17 | } 18 | 19 | const ReactFunctionalComponent: FC = ( 20 | props: ReactFunctionalComponentProps 21 | ) => ( 22 | <> 23 | 28 | 29 | 30 | 31 | FC} 35 | > 36 | props]} 38 | returnStatement={props.children || null} 39 | returnType="ReactNode" 40 | /> 41 | 42 | 43 | {props.name} 44 | 45 | 46 | ); 47 | 48 | export default ReactFunctionalComponent; 49 | -------------------------------------------------------------------------------- /phaseL/src/components/ClassProperty/ClassProperty.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component, ReactNode } from 'react'; 2 | import { Smart, TypeAnnotation } from '../..'; 3 | 4 | export interface ClassPropertyProps { 5 | children?: ReactNode; 6 | name: string; 7 | static?: boolean; 8 | type?: ReactNode; 9 | } 10 | 11 | export class ClassProperty extends Component { 12 | static defaultProps = { 13 | static: false 14 | }; 15 | 16 | renderChildren() { 17 | if (typeof this.props.children === 'string') { 18 | const code = `'${this.props.children}'`; 19 | return ; 20 | } 21 | if ( 22 | typeof this.props.children === 'number' || 23 | typeof this.props.children === 'boolean' 24 | ) { 25 | return ( 26 | 27 | ); 28 | } 29 | return this.props.children; 30 | } 31 | 32 | renderTypeAnnotation() { 33 | return typeof this.props.type === 'string' ? ( 34 | {this.props.type} 35 | ) : ( 36 | this.props.type 37 | ); 38 | } 39 | 40 | render() { 41 | const code = `class C {${this.props.static ? 'static ' : ''}${ 42 | this.props.name 43 | } = null}`; 44 | return ( 45 | 46 | {this.renderTypeAnnotation()} 47 | {this.renderChildren()} 48 | 49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /phaseA/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # parcel-bundler cache (https://parceljs.org/) 61 | .cache 62 | 63 | # next.js build output 64 | .next 65 | 66 | # nuxt.js build output 67 | .nuxt 68 | 69 | # vuepress build output 70 | .vuepress/dist 71 | 72 | # Serverless directories 73 | .serverless 74 | 75 | package-lock.json 76 | yarn.lock 77 | .tern-port 78 | .DS_Store 79 | tsconfig.tsbuildinfo 80 | .tmp 81 | lib 82 | -------------------------------------------------------------------------------- /phaseB/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # parcel-bundler cache (https://parceljs.org/) 61 | .cache 62 | 63 | # next.js build output 64 | .next 65 | 66 | # nuxt.js build output 67 | .nuxt 68 | 69 | # vuepress build output 70 | .vuepress/dist 71 | 72 | # Serverless directories 73 | .serverless 74 | 75 | package-lock.json 76 | yarn.lock 77 | .tern-port 78 | .DS_Store 79 | tsconfig.tsbuildinfo 80 | .tmp 81 | lib 82 | -------------------------------------------------------------------------------- /phaseC/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # parcel-bundler cache (https://parceljs.org/) 61 | .cache 62 | 63 | # next.js build output 64 | .next 65 | 66 | # nuxt.js build output 67 | .nuxt 68 | 69 | # vuepress build output 70 | .vuepress/dist 71 | 72 | # Serverless directories 73 | .serverless 74 | 75 | package-lock.json 76 | yarn.lock 77 | .tern-port 78 | .DS_Store 79 | tsconfig.tsbuildinfo 80 | .tmp 81 | lib 82 | -------------------------------------------------------------------------------- /phaseD/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # parcel-bundler cache (https://parceljs.org/) 61 | .cache 62 | 63 | # next.js build output 64 | .next 65 | 66 | # nuxt.js build output 67 | .nuxt 68 | 69 | # vuepress build output 70 | .vuepress/dist 71 | 72 | # Serverless directories 73 | .serverless 74 | 75 | package-lock.json 76 | yarn.lock 77 | .tern-port 78 | .DS_Store 79 | tsconfig.tsbuildinfo 80 | .tmp 81 | lib 82 | -------------------------------------------------------------------------------- /phaseE/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # parcel-bundler cache (https://parceljs.org/) 61 | .cache 62 | 63 | # next.js build output 64 | .next 65 | 66 | # nuxt.js build output 67 | .nuxt 68 | 69 | # vuepress build output 70 | .vuepress/dist 71 | 72 | # Serverless directories 73 | .serverless 74 | 75 | package-lock.json 76 | yarn.lock 77 | .tern-port 78 | .DS_Store 79 | tsconfig.tsbuildinfo 80 | .tmp 81 | lib 82 | -------------------------------------------------------------------------------- /phaseF/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # parcel-bundler cache (https://parceljs.org/) 61 | .cache 62 | 63 | # next.js build output 64 | .next 65 | 66 | # nuxt.js build output 67 | .nuxt 68 | 69 | # vuepress build output 70 | .vuepress/dist 71 | 72 | # Serverless directories 73 | .serverless 74 | 75 | package-lock.json 76 | yarn.lock 77 | .tern-port 78 | .DS_Store 79 | tsconfig.tsbuildinfo 80 | .tmp 81 | lib 82 | --------------------------------------------------------------------------------