├── examples └── todo-mvc │ ├── .gitignore │ ├── assets │ ├── icon.png │ └── favicon.ico │ ├── README.md │ ├── src │ ├── components │ │ ├── app.js │ │ ├── header.js │ │ ├── todo-text-input.js │ │ ├── main-section.js │ │ ├── todo-item.js │ │ └── footer.js │ ├── manifest.json │ ├── index.js │ └── store.js │ └── package.json ├── .github ├── logo.png └── logo.svg ├── devtools ├── index.d.ts ├── package.json └── src │ └── index.js ├── .travis.yml ├── preact ├── tsconfig.json ├── package.json └── src │ └── index.ts ├── react ├── tsconfig.json ├── package.json └── src │ └── index.ts ├── greenkeeper.json ├── src ├── util.ts ├── symbols.ts ├── emitter.ts └── index.ts ├── .editorconfig ├── .gitignore ├── do-not-git-test.js ├── .babelrc ├── tsconfig.json ├── CODE_OF_CONDUCT.md ├── package.json ├── README.md └── test └── model.test.ts /examples/todo-mvc/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /build 3 | /*.log -------------------------------------------------------------------------------- /.github/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ForsakenHarmony/parket/HEAD/.github/logo.png -------------------------------------------------------------------------------- /devtools/index.d.ts: -------------------------------------------------------------------------------- 1 | import { Model } from 'parket'; 2 | 3 | export default function (model: Model): void; 4 | -------------------------------------------------------------------------------- /examples/todo-mvc/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ForsakenHarmony/parket/HEAD/examples/todo-mvc/assets/icon.png -------------------------------------------------------------------------------- /examples/todo-mvc/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ForsakenHarmony/parket/HEAD/examples/todo-mvc/assets/favicon.ico -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - lts/* 4 | - node 5 | script: 6 | - yarn test-ci 7 | after_success: 8 | - yarn coveralls 9 | -------------------------------------------------------------------------------- /preact/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "dist/es" 5 | }, 6 | "files": ["src/index.ts"] 7 | } 8 | -------------------------------------------------------------------------------- /react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "dist/es" 5 | }, 6 | "files": ["src/index.ts"] 7 | } 8 | -------------------------------------------------------------------------------- /greenkeeper.json: -------------------------------------------------------------------------------- 1 | { 2 | "groups": { 3 | "default": { 4 | "packages": [ 5 | "examples/todo-mvc/package.json", 6 | "package.json" 7 | ] 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/todo-mvc/README.md: -------------------------------------------------------------------------------- 1 | # parket-todo-mvc 2 | 3 | This is adapted from the mobx-state-tree example to show the similarities 4 | 5 | ### Try it 6 | 7 | ``` 8 | $ npm install 9 | 10 | $ npm run start 11 | ``` 12 | -------------------------------------------------------------------------------- /src/util.ts: -------------------------------------------------------------------------------- 1 | // Lighter Object.assign stand-in 2 | export function assign( 3 | obj: { [index: string]: any }, 4 | props: { [index: string]: any } 5 | ) { 6 | for (let i in props) obj[i] = props[i]; 7 | return obj; 8 | } 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .vscode 3 | 4 | node_modules 5 | npm-debug.log 6 | 7 | dist/ 8 | /preact.js 9 | /preact.js.map 10 | /react.js 11 | /react.js.map 12 | /devtools.js 13 | /devtools.js.map 14 | /coverage 15 | 16 | package-lock.json 17 | .rpt2_cache 18 | 19 | *.log 20 | -------------------------------------------------------------------------------- /src/symbols.ts: -------------------------------------------------------------------------------- 1 | export const parentSymbol = Symbol('parent'); 2 | export const modelSymbol = Symbol('model'); 3 | export const vpc = Symbol('viewProxyCache'); 4 | export const apc = Symbol('actionProxyCache'); 5 | export const observed = '__p_observed'; 6 | export const modelName = '__p_model'; 7 | -------------------------------------------------------------------------------- /examples/todo-mvc/src/components/app.js: -------------------------------------------------------------------------------- 1 | import { Header } from './header'; 2 | import { MainSection } from './main-section'; 3 | 4 | export const App = ({ store }) => ( 5 |
6 |
7 | 8 |
9 | ); 10 | -------------------------------------------------------------------------------- /do-not-git-test.js: -------------------------------------------------------------------------------- 1 | const model = require('./'); 2 | 3 | const foo = { connected: false }; 4 | 5 | const Test = model('test', () => ({ 6 | ...foo, 7 | 8 | get isConnected() { 9 | return this.connected; 10 | }, 11 | })); 12 | 13 | const instance = Test(); 14 | console.log(instance.connected); // true 15 | console.log(instance.isConnected); // undefined 16 | -------------------------------------------------------------------------------- /examples/todo-mvc/src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todo-mvc", 3 | "short_name": "todo-mvc", 4 | "start_url": "/", 5 | "display": "standalone", 6 | "orientation": "portrait", 7 | "background_color": "#fff", 8 | "theme_color": "#673ab8", 9 | "icons": [ 10 | { 11 | "src": "/assets/icon.png", 12 | "type": "image/png", 13 | "sizes": "512x512" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /devtools/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@parket/devtools", 3 | "version": "0.1.0", 4 | "private": true, 5 | "types": "dist/index.d.ts", 6 | "source": "src/index.js", 7 | "main": "dist/index.js", 8 | "scripts": { 9 | "build": "npm-run-all --silent -p build:*", 10 | "build:main": "microbundle build -f cjs", 11 | "build:ts": "tsc" 12 | }, 13 | "peerDependencies": { 14 | "parket": "^0.6.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "targets": { 7 | "node": true 8 | } 9 | } 10 | ] 11 | ], 12 | "plugins": [ 13 | [ 14 | "transform-react-jsx", 15 | { 16 | "pragma": "h" 17 | } 18 | ], 19 | [ 20 | "jsx-pragmatic", 21 | { 22 | "module": "preact", 23 | "export": "h", 24 | "import": "h" 25 | } 26 | ] 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /preact/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@parket/preact", 3 | "version": "0.1.0", 4 | "private": true, 5 | "types": "dist/index.d.ts", 6 | "source": "src/index.ts", 7 | "main": "dist/index.js", 8 | "module": "dist/es/index.js", 9 | "umd:main": "dist/parket-preact.umd.js", 10 | "scripts": { 11 | "build": "npm-run-all --silent -p build:*", 12 | "build:main": "microbundle build", 13 | "build:ts": "tsc" 14 | }, 15 | "peerDependencies": { 16 | "parket": "^0.6.0", 17 | "preact": "^10.4.1" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@parket/react", 3 | "version": "0.1.0", 4 | "private": true, 5 | "types": "dist/index.d.ts", 6 | "source": "src/index.ts", 7 | "main": "dist/index.js", 8 | "module": "dist/es/index.js", 9 | "umd:main": "dist/parket-react.umd.js", 10 | "scripts": { 11 | "build": "npm-run-all --silent -p build:*", 12 | "build:main": "microbundle build", 13 | "build:ts": "tsc" 14 | }, 15 | "peerDependencies": { 16 | "parket": "^0.6.0", 17 | "@types/react": "^10.4.1", 18 | "react": "^16.13.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/todo-mvc/src/components/header.js: -------------------------------------------------------------------------------- 1 | import { Component } from 'preact'; 2 | 3 | import { TodoTextInput } from './todo-text-input'; 4 | 5 | export class Header extends Component { 6 | handleSave = (text) => { 7 | if (text.length !== 0) { 8 | this.props.addTodo(text); 9 | } 10 | }; 11 | 12 | render() { 13 | return ( 14 |
15 |

todos

16 | 21 |
22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /examples/todo-mvc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "todo-mvc", 4 | "version": "0.0.0", 5 | "license": "MIT", 6 | "main": "src", 7 | "scripts": { 8 | "build": "preact build", 9 | "dev": "preact watch", 10 | "lint": "eslint src" 11 | }, 12 | "eslintConfig": { 13 | "extends": "eslint-config-synacor" 14 | }, 15 | "eslintIgnore": [ 16 | "build/*" 17 | ], 18 | "devDependencies": { 19 | "eslint": "^6.8.0", 20 | "eslint-config-synacor": "^3.0.5", 21 | "preact-cli": "^3.0.0-rc.10", 22 | "preact-render-to-string": "^5.1.6" 23 | }, 24 | "dependencies": { 25 | "clsx": "^1.1.0", 26 | "parket": "^0.5.0", 27 | "preact": "^10.4.0", 28 | "todomvc-app-css": "^2.3.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "jsx": "react", 8 | "jsxFactory": "h", 9 | "noImplicitAny": true, 10 | "experimentalDecorators": true, 11 | "strictNullChecks": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "noImplicitReturns": true, 14 | "noImplicitThis": true, 15 | "noUnusedLocals": true, 16 | "noUnusedParameters": true, 17 | "lib": ["es2015", "dom"], 18 | "outDir": "dist/es", 19 | "esModuleInterop": true, 20 | "baseUrl": ".", 21 | "paths": { 22 | "parket": ["."], 23 | "parket/*": ["./*"], 24 | "preact": ["./node_modules/preact"], 25 | "react": ["./node_modules/react"] 26 | } 27 | }, 28 | "files": ["src/index.ts"], 29 | "exclude": ["dist/**/*", "parket-react/dist", "preact/dist", "node_modules"] 30 | } 31 | -------------------------------------------------------------------------------- /examples/todo-mvc/src/index.js: -------------------------------------------------------------------------------- 1 | import 'todomvc-app-css/index.css'; 2 | import devtools from 'parket/devtools'; 3 | 4 | import { TodoStore } from './store'; 5 | import { App } from './components/app'; 6 | 7 | const localStorageKey = 'parket-todomvc-example'; 8 | const initialState = localStorage.getItem(localStorageKey) 9 | ? JSON.parse(localStorage.getItem(localStorageKey)) 10 | : { 11 | todos: [ 12 | { 13 | text: 'learn Mobx', 14 | completed: false, 15 | id: 0, 16 | __p_model: 'Todo', 17 | }, 18 | { 19 | text: 'learn MST', 20 | completed: false, 21 | id: 1, 22 | __p_model: 'Todo', 23 | }, 24 | ], 25 | }; 26 | 27 | const store = TodoStore(initialState); 28 | 29 | devtools(store); 30 | 31 | store.onSnapshot((snapshot) => { 32 | localStorage.setItem(localStorageKey, JSON.stringify(snapshot)); 33 | }); 34 | 35 | store.onAction(console.log.bind(console, 'action')); 36 | store.onPatch(console.log.bind(console, 'patch')); 37 | store.onSnapshot(console.log.bind(console, 'snapshot')); 38 | 39 | global.store = store; 40 | 41 | export default () => ; 42 | -------------------------------------------------------------------------------- /examples/todo-mvc/src/components/todo-text-input.js: -------------------------------------------------------------------------------- 1 | import { Component } from 'preact'; 2 | import cls from 'clsx'; 3 | 4 | export class TodoTextInput extends Component { 5 | state = { 6 | text: this.props.text || '', 7 | }; 8 | 9 | handleSubmit = (e) => { 10 | const text = e.target.value.trim(); 11 | if (e.which === 13) { 12 | this.props.onSave(text); 13 | if (this.props.newTodo) { 14 | this.setState({ text: '' }); 15 | } 16 | } 17 | }; 18 | 19 | handleChange = (e) => { 20 | this.setState({ text: e.target.value }); 21 | }; 22 | 23 | handleBlur = (e) => { 24 | if (!this.props.newTodo) { 25 | this.props.onSave(e.target.value); 26 | } 27 | }; 28 | 29 | render({ editing, newTodo }) { 30 | return ( 31 | 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /examples/todo-mvc/src/components/main-section.js: -------------------------------------------------------------------------------- 1 | import { Component } from 'preact'; 2 | import { observe } from 'parket/preact'; 3 | 4 | import { TodoItem } from './todo-item'; 5 | import { Footer } from './footer'; 6 | 7 | @observe 8 | export class MainSection extends Component { 9 | handleClearCompleted = () => { 10 | this.props.store.clearCompleted(); 11 | }; 12 | 13 | renderToggleAll() { 14 | const { store } = this.props; 15 | if (store.todos.length > 0) { 16 | return ( 17 | 18 | store.completeAll()} 24 | /> 25 | 26 | 27 | ); 28 | } 29 | } 30 | 31 | renderFooter(completedCount) { 32 | const { store } = this.props; 33 | 34 | if (store.todos.length) { 35 | return