├── packages ├── fluxible-router │ ├── .eslintignore │ ├── .npmignore │ ├── src │ │ ├── NavLink.js │ │ └── index.js │ ├── .babelrc.json │ ├── docs │ │ ├── README.md │ │ ├── api │ │ │ ├── README.md │ │ │ ├── createNavLinkComponent.md │ │ │ └── handleRoute.md │ │ └── guides │ │ │ ├── scrolling.md │ │ │ └── history.md │ ├── tests │ │ ├── mocks │ │ │ └── MockAppComponent.js │ │ └── unit │ │ │ └── handleRoute.test.js │ └── CONTRIBUTING.md ├── dispatchr │ ├── .npmignore │ ├── utils │ │ ├── index.js │ │ ├── BaseStore.js │ │ └── createStore.js │ ├── addons │ │ └── index.js │ ├── index.js │ ├── CHANGELOG.md │ ├── package.json │ ├── tests │ │ ├── unit │ │ │ └── addons │ │ │ │ └── BaseStore.test.js │ │ └── mock │ │ │ ├── NoDehydrate.js │ │ │ └── DelayedStore.js │ └── CONTRIBUTING.md ├── generator-fluxible │ ├── .yo-rc.json │ ├── .npmignore │ ├── CHANGELOG.md │ ├── app │ │ ├── templates │ │ │ ├── stores │ │ │ │ ├── RouteStore.js │ │ │ │ └── ApplicationStore.js │ │ │ ├── components │ │ │ │ ├── Home.js │ │ │ │ ├── About.js │ │ │ │ ├── Html.js │ │ │ │ ├── Nav.js │ │ │ │ └── Application.js │ │ │ ├── babel.config.js │ │ │ ├── app.js │ │ │ ├── configs │ │ │ │ └── routes.js │ │ │ ├── client.js │ │ │ ├── webpack.config.js │ │ │ └── package.json │ │ └── index.js │ ├── README.md │ ├── package.json │ └── tests │ │ └── unit │ │ └── test-app.test.js ├── fluxible-plugin-fetchr │ ├── .npmignore │ ├── index.js │ ├── tests │ │ └── fixtures │ │ │ └── services │ │ │ └── mockService.js │ ├── package.json │ ├── CONTRIBUTING.md │ └── utils │ │ └── MockServiceManager.js ├── fluxible-reducer-store │ ├── UPGRADE.md │ ├── CHANGELOG.md │ ├── index.js │ ├── .npmignore │ ├── tests │ │ └── fixtures │ │ │ └── stores │ │ │ └── SingleReducerStore.js │ └── package.json ├── fluxible │ ├── .npmignore │ ├── utils │ │ ├── index.js │ │ ├── generateUUID.js │ │ ├── createMockActionContext.js │ │ ├── createMockComponentContext.js │ │ ├── deprecateComponent.js │ │ ├── MockComponentContext.js │ │ ├── MockActionContext.js │ │ └── promiseCallback.js │ ├── addons │ │ ├── BaseStore.js │ │ ├── createStore.js │ │ └── index.js │ ├── index.js │ ├── tests │ │ └── fixtures │ │ │ ├── stores │ │ │ ├── BarStore.js │ │ │ └── FooStore.js │ │ │ └── plugins │ │ │ ├── DimensionsContextPluginSync.js │ │ │ ├── DimensionsContextPlugin.js │ │ │ └── DimensionsContextPluginPromise.js │ ├── docs │ │ └── api │ │ │ └── addons │ │ │ ├── createStore.md │ │ │ └── BaseStore.md │ └── package.json ├── fluxible-plugin-devtools │ ├── src │ │ ├── lib │ │ │ └── CONSTANTS.js │ │ └── components │ │ │ └── Actions.jsx │ ├── .npmignore │ ├── index.js │ ├── docs │ │ └── fluxible-plugin-devtools.md │ ├── CHANGELOG.md │ ├── package.json │ └── README.md └── fluxible-addons-react │ ├── .npmignore │ ├── docs │ └── api │ │ ├── useFluxible.md │ │ ├── withFluxible.md │ │ ├── batchedUpdatePlugin.md │ │ ├── createElementWithContext.md │ │ ├── provideContext.md │ │ └── FluxibleComponent.md │ ├── tests │ ├── fixtures │ │ └── stores │ │ │ ├── BarStore.js │ │ │ └── FooStore.js │ └── unit │ │ └── lib │ │ ├── useFluxible.test.js │ │ └── withFluxible.test.js │ ├── .babelrc.json │ ├── src │ ├── FluxibleComponentContext.js │ ├── FluxibleProvider.js │ ├── useFluxible.js │ ├── FluxibleComponent.js │ ├── index.js │ ├── batchedUpdatePlugin.js │ ├── withFluxible.js │ ├── createElementWithContext.js │ └── provideContext.js │ ├── package.json │ └── CONTRIBUTING.md ├── .npmrc ├── .prettierrc.json ├── examples ├── doc-site │ ├── .eslintignore │ ├── assets │ │ ├── images │ │ │ ├── favicon.ico │ │ │ └── splash_background.jpg │ │ └── css │ │ │ └── ie.css │ ├── .gitignore │ ├── .mocharc.js │ ├── .babelrc │ ├── .nycrc │ ├── actions │ │ ├── demoException.js │ │ ├── doSearch.js │ │ ├── showHome.js │ │ ├── showSearch.js │ │ ├── loadIndex.js │ │ └── showDoc.js │ ├── configs │ │ ├── redirects.js │ │ └── atomic.js │ ├── tests │ │ ├── fixtures │ │ │ └── doc-response.js │ │ └── unit │ │ │ └── actions │ │ │ ├── demoException.js │ │ │ ├── doSearch.js │ │ │ ├── showSearch.js │ │ │ └── loadIndex.js │ ├── utils │ │ ├── getSearchIndexPath.js │ │ ├── assets.js │ │ └── renderer.js │ ├── start.js │ ├── secrets.js │ ├── services │ │ └── search.js │ ├── .eslintrc.js │ ├── client.js │ ├── components │ │ ├── Status500.js │ │ └── Status404.js │ ├── plugins │ │ └── queryPlugin.js │ └── app.js ├── chat │ ├── .babelrc │ ├── stores │ │ ├── RouteStore.js │ │ └── UnreadThreadStore.js │ ├── start.js │ ├── webpack.config.js │ ├── app.js │ ├── README.md │ ├── actions │ │ ├── openThread.js │ │ ├── showChat.js │ │ └── createMessage.js │ ├── configs │ │ └── routes.js │ ├── components │ │ ├── ChatApp.js │ │ ├── MessageListItem.js │ │ ├── Html.js │ │ └── ThreadListItem.js │ └── package.json ├── todo │ ├── .babelrc │ ├── assets │ │ ├── todomvc-common │ │ │ └── bg.png │ │ └── styles.css │ ├── start.js │ ├── README.md │ ├── app.js │ ├── actions │ │ ├── deleteTodo.js │ │ ├── updateTodo.js │ │ ├── showTodos.js │ │ ├── toggleAll.js │ │ └── createTodo.js │ ├── webpack.config.js │ ├── client.js │ ├── stores │ │ └── PageStore.js │ └── package.json ├── react-router │ ├── .babelrc │ ├── actions │ │ ├── navigate.js │ │ └── updateTime.js │ ├── start.js │ ├── components │ │ ├── Home.js │ │ ├── About.js │ │ ├── Routes.js │ │ ├── Application.js │ │ ├── Timestamp.js │ │ ├── Page.js │ │ ├── Nav.js │ │ └── Html.js │ ├── README.md │ ├── app.js │ ├── webpack.config.js │ ├── stores │ │ ├── PageStore.js │ │ ├── TimeStore.js │ │ └── ApplicationStore.js │ ├── package.json │ └── client.js ├── fluxible-router │ ├── .babelrc │ ├── stores │ │ ├── RouteStore.js │ │ ├── PageStore.js │ │ ├── TimeStore.js │ │ └── ApplicationStore.js │ ├── start.js │ ├── actions │ │ └── updateTime.js │ ├── components │ │ ├── Home.js │ │ ├── About.js │ │ ├── Page.js │ │ ├── Timestamp.js │ │ ├── Application.js │ │ └── Html.js │ ├── browser-only │ │ ├── index.html │ │ ├── webpack.config.js │ │ └── browser-only.js │ ├── app.js │ ├── webpack.config.js │ ├── README.md │ ├── client.js │ └── package.json ├── minimal │ ├── src │ │ ├── actions.js │ │ ├── fluxibleApp.js │ │ ├── App.js │ │ ├── AppStore.js │ │ ├── browser.js │ │ ├── RandomNumberGenerator.js │ │ └── server.js │ ├── babel.config.js │ ├── README.md │ ├── package.json │ └── webpack.config.js ├── create-react-app │ ├── src │ │ ├── actions.js │ │ ├── fluxibleApp.js │ │ ├── App.js │ │ ├── index.js │ │ ├── AppStore.js │ │ └── RandomNumberGenerator.js │ ├── .gitignore │ ├── package.json │ └── public │ │ └── index.html └── stale-props │ ├── src │ ├── fluxibleApp.js │ ├── App.js │ ├── actions.js │ ├── List.js │ ├── index.js │ ├── Input.js │ ├── ListStore.js │ └── Item.js │ ├── public │ └── index.html │ ├── package.json │ └── README.md ├── .prettierignore ├── .eslintignore ├── babel.config.json ├── jest.config.js ├── .gitignore ├── .github ├── dependabot.yml ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md └── workflows │ └── node.js.yml ├── .changeset ├── config.json └── README.md ├── CONTRIBUTING.md ├── .eslintrc.js └── docs ├── quick-start.md ├── README.md ├── home.md └── community └── articles.md /packages/fluxible-router/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | legacy-peer-deps = true 2 | package-lock = false 3 | -------------------------------------------------------------------------------- /packages/dispatchr/.npmignore: -------------------------------------------------------------------------------- 1 | /artifacts/ 2 | /docs/ 3 | /tests/ 4 | -------------------------------------------------------------------------------- /packages/generator-fluxible/.yo-rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "generator-generator": {} 3 | } -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "tabWidth": 4 4 | } 5 | -------------------------------------------------------------------------------- /examples/doc-site/.eslintignore: -------------------------------------------------------------------------------- 1 | artifacts 2 | build 3 | node_modules 4 | dist 5 | -------------------------------------------------------------------------------- /examples/chat/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env", "@babel/preset-react"] 3 | } 4 | -------------------------------------------------------------------------------- /examples/todo/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env", "@babel/preset-react"] 3 | } 4 | -------------------------------------------------------------------------------- /packages/fluxible-plugin-fetchr/.npmignore: -------------------------------------------------------------------------------- 1 | /artifacts/ 2 | /docs/ 3 | /tests/ 4 | .npmignore 5 | -------------------------------------------------------------------------------- /packages/fluxible-reducer-store/UPGRADE.md: -------------------------------------------------------------------------------- 1 | # Upgrade Guide 2 | 3 | No breaking changes yet. 4 | -------------------------------------------------------------------------------- /packages/fluxible-reducer-store/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## 0.1.0 4 | 5 | First version. 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.json 3 | *.md 4 | *.yml 5 | .nyc_output 6 | build 7 | coverage 8 | dist 9 | -------------------------------------------------------------------------------- /examples/react-router/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env", "@babel/preset-react"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | artifacts 2 | build 3 | dist 4 | node_modules 5 | **/artifacts 6 | **/build 7 | **/node_modules 8 | -------------------------------------------------------------------------------- /examples/fluxible-router/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env", "@babel/preset-react"] 3 | } 4 | -------------------------------------------------------------------------------- /packages/fluxible-router/.npmignore: -------------------------------------------------------------------------------- 1 | .* 2 | /artifacts/ 3 | /docs/ 4 | /src/ 5 | /tests/ 6 | *.log 7 | *.md 8 | *.tgz 9 | -------------------------------------------------------------------------------- /packages/fluxible/.npmignore: -------------------------------------------------------------------------------- 1 | artifacts 2 | docs 3 | tests 4 | .idea 5 | *.log 6 | .coveralls 7 | .npmignore 8 | .travis.yml 9 | -------------------------------------------------------------------------------- /babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env", "@babel/preset-react"], 3 | "babelrcRoots": ["packages/*"] 4 | } 5 | -------------------------------------------------------------------------------- /packages/fluxible-plugin-devtools/src/lib/CONSTANTS.js: -------------------------------------------------------------------------------- 1 | export const ACTION = 'action'; 2 | export const DISPATCH = 'dispatch'; 3 | -------------------------------------------------------------------------------- /examples/doc-site/assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/fluxible/HEAD/examples/doc-site/assets/images/favicon.ico -------------------------------------------------------------------------------- /examples/todo/assets/todomvc-common/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/fluxible/HEAD/examples/todo/assets/todomvc-common/bg.png -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: { 3 | '\\.js$': ['babel-jest', { cwd: __dirname }], 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /packages/fluxible-reducer-store/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | createReducerStore: require('./lib/createReducerStore'), 3 | }; 4 | -------------------------------------------------------------------------------- /packages/generator-fluxible/.npmignore: -------------------------------------------------------------------------------- 1 | artifacts 2 | docs 3 | tests 4 | .idea 5 | *.log 6 | .coveralls 7 | .npmignore 8 | .travis.yml 9 | -------------------------------------------------------------------------------- /packages/dispatchr/utils/index.js: -------------------------------------------------------------------------------- 1 | throw new Error( 2 | "require('dispatchr/utils') has moved to require('dispatchr/addons')", 3 | ); 4 | -------------------------------------------------------------------------------- /packages/fluxible-reducer-store/.npmignore: -------------------------------------------------------------------------------- 1 | artifacts 2 | docs 3 | tests 4 | .idea 5 | *.log 6 | .coveralls 7 | .npmignore 8 | .travis.yml 9 | -------------------------------------------------------------------------------- /examples/doc-site/assets/images/splash_background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/fluxible/HEAD/examples/doc-site/assets/images/splash_background.jpg -------------------------------------------------------------------------------- /packages/dispatchr/addons/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | BaseStore: require('./BaseStore'), 3 | createStore: require('./createStore'), 4 | }; 5 | -------------------------------------------------------------------------------- /examples/doc-site/.gitignore: -------------------------------------------------------------------------------- 1 | /.sass-cache 2 | /build/ 3 | /screwdriver/ 4 | /assets.js 5 | /deploy.json 6 | /grasshopper.json 7 | /replicatr.js 8 | /secrets/ 9 | -------------------------------------------------------------------------------- /packages/fluxible-plugin-devtools/.npmignore: -------------------------------------------------------------------------------- 1 | artifacts 2 | docs 3 | src 4 | tests 5 | .idea 6 | *.log 7 | .coveralls 8 | .npmignore 9 | .travis.yml 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .nyc_output 2 | coverage 3 | dist 4 | artifacts 5 | node_modules 6 | *.log 7 | *.tgz 8 | .jshintrc 9 | *.sh 10 | examples/*/build 11 | temp/ 12 | -------------------------------------------------------------------------------- /packages/dispatchr/utils/BaseStore.js: -------------------------------------------------------------------------------- 1 | throw new Error( 2 | "require('dispatchr/utils/BaseStore') has moved to require('dispatchr/addons/BaseStore')", 3 | ); 4 | -------------------------------------------------------------------------------- /examples/doc-site/.mocharc.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | recursive: true, 5 | reporter: 'spec', 6 | timeout: 10000, 7 | }; 8 | -------------------------------------------------------------------------------- /examples/todo/assets/styles.css: -------------------------------------------------------------------------------- 1 | #todo-list li.pending { 2 | background-color: #ffedd0; 3 | } 4 | #todo-list li.failure { 5 | background-color: #ffc9c4; 6 | } 7 | -------------------------------------------------------------------------------- /packages/dispatchr/utils/createStore.js: -------------------------------------------------------------------------------- 1 | throw new Error( 2 | "require('dispatchr/utils/createStore') has moved to require('dispatchr/addons/createStore')", 3 | ); 4 | -------------------------------------------------------------------------------- /packages/generator-fluxible/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # generator-fluxible 2 | 3 | ## 2.0.0 4 | 5 | ### Major Changes 6 | 7 | - 10fea13: feat: upgrade to latest yeoman packages 8 | -------------------------------------------------------------------------------- /examples/react-router/actions/navigate.js: -------------------------------------------------------------------------------- 1 | module.exports = function (actionContext, payload, done) { 2 | actionContext.dispatch('CHANGE_ROUTE', payload); 3 | done(); 4 | }; 5 | -------------------------------------------------------------------------------- /packages/fluxible-addons-react/.npmignore: -------------------------------------------------------------------------------- 1 | artifacts 2 | docs 3 | src 4 | tests 5 | .idea 6 | *.log 7 | *.md 8 | .babelrc.json 9 | .coveralls 10 | .npmignore 11 | .travis.yml 12 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: weekly 7 | time: "13:00" 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /examples/fluxible-router/stores/RouteStore.js: -------------------------------------------------------------------------------- 1 | import { RouteStore } from 'fluxible-router'; 2 | import routes from '../configs/routes'; 3 | 4 | export default RouteStore.withStaticRoutes(routes); 5 | -------------------------------------------------------------------------------- /examples/chat/stores/RouteStore.js: -------------------------------------------------------------------------------- 1 | var RouteStore = require('fluxible-router').RouteStore; 2 | var routes = require('../configs/routes'); 3 | 4 | module.exports = RouteStore.withStaticRoutes(routes); 5 | -------------------------------------------------------------------------------- /examples/doc-site/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env", "@babel/preset-react"], 3 | "env": { 4 | "test": { 5 | "plugins": ["istanbul"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/minimal/src/actions.js: -------------------------------------------------------------------------------- 1 | export const setRandomNumber = (context) => { 2 | const number = Math.floor(Math.random() * Math.floor(100)); 3 | context.dispatch('SET_NUMBER', { number }); 4 | }; 5 | -------------------------------------------------------------------------------- /examples/doc-site/.nycrc: -------------------------------------------------------------------------------- 1 | { 2 | "reporter": "lcov", 3 | "sourceMap": false, 4 | "instrument": false, 5 | "extends": "@istanbuljs/nyc-config-babel", 6 | "exclude": ["components/**/*"] 7 | } 8 | -------------------------------------------------------------------------------- /packages/fluxible/utils/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | createMockActionContext: require('./createMockActionContext'), 3 | createMockComponentContext: require('./createMockComponentContext'), 4 | }; 5 | -------------------------------------------------------------------------------- /examples/create-react-app/src/actions.js: -------------------------------------------------------------------------------- 1 | export const setRandomNumber = (context) => { 2 | const number = Math.floor(Math.random() * Math.floor(100)); 3 | context.dispatch('SET_NUMBER', { number }); 4 | }; 5 | -------------------------------------------------------------------------------- /packages/generator-fluxible/app/templates/stores/RouteStore.js: -------------------------------------------------------------------------------- 1 | import { RouteStore } from 'fluxible-router'; 2 | import routes from '../configs/routes'; 3 | 4 | export default RouteStore.withStaticRoutes(routes); 5 | -------------------------------------------------------------------------------- /packages/dispatchr/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | module.exports = require('./lib/Dispatcher'); 6 | -------------------------------------------------------------------------------- /packages/fluxible-plugin-fetchr/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | module.exports = require('./lib/fetchr-plugin'); 6 | -------------------------------------------------------------------------------- /examples/stale-props/src/fluxibleApp.js: -------------------------------------------------------------------------------- 1 | import Fluxible from 'fluxible'; 2 | import ListStore from './ListStore'; 3 | 4 | const fluxibleApp = new Fluxible({}); 5 | 6 | fluxibleApp.registerStore(ListStore); 7 | 8 | export default fluxibleApp; 9 | -------------------------------------------------------------------------------- /examples/stale-props/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Stale props example 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/chat/start.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | require('@babel/register'); 7 | 8 | module.exports = require('./server'); 9 | -------------------------------------------------------------------------------- /examples/todo/start.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | require('@babel/register'); 7 | 8 | module.exports = require('./server'); 9 | -------------------------------------------------------------------------------- /packages/fluxible/addons/BaseStore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | 7 | module.exports = require('dispatchr/addons/BaseStore'); 8 | -------------------------------------------------------------------------------- /packages/fluxible/addons/createStore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | 7 | module.exports = require('dispatchr/addons/createStore'); 8 | -------------------------------------------------------------------------------- /examples/react-router/start.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | require('@babel/register'); 7 | 8 | module.exports = require('./server'); 9 | -------------------------------------------------------------------------------- /examples/fluxible-router/start.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | require('@babel/register'); 7 | 8 | module.exports = require('./server'); 9 | -------------------------------------------------------------------------------- /examples/stale-props/src/App.js: -------------------------------------------------------------------------------- 1 | import List from './List'; 2 | import Input from './Input'; 3 | 4 | function App() { 5 | return ( 6 |
7 | 8 | 9 |
10 | ); 11 | } 12 | 13 | export default App; 14 | -------------------------------------------------------------------------------- /packages/generator-fluxible/app/templates/components/Home.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default function Home() { 4 | return ( 5 |
6 |

Home

7 |

Welcome to the site!

8 |
9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /examples/minimal/src/fluxibleApp.js: -------------------------------------------------------------------------------- 1 | import Fluxible from 'fluxible'; 2 | import App from './App'; 3 | import AppStore from './AppStore'; 4 | 5 | const fluxibleApp = new Fluxible({ component: App }); 6 | 7 | fluxibleApp.registerStore(AppStore); 8 | 9 | export default fluxibleApp; 10 | -------------------------------------------------------------------------------- /examples/create-react-app/src/fluxibleApp.js: -------------------------------------------------------------------------------- 1 | import Fluxible from 'fluxible'; 2 | import App from './App'; 3 | import AppStore from './AppStore'; 4 | 5 | const fluxibleApp = new Fluxible({ component: App }); 6 | 7 | fluxibleApp.registerStore(AppStore); 8 | 9 | export default fluxibleApp; 10 | -------------------------------------------------------------------------------- /examples/doc-site/actions/demoException.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 6 | export default function demoException(context, route, done) { 7 | done(new Error('Whoops!')); 8 | } 9 | -------------------------------------------------------------------------------- /packages/generator-fluxible/app/templates/components/About.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default function About() { 4 | return ( 5 |
6 |

About

7 |

This is a description of the site.

8 |
9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /packages/fluxible/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | var Fluxible = require('./lib/Fluxible'); 6 | Fluxible.Fluxible = require('./lib/Fluxible'); 7 | 8 | module.exports = Fluxible; 9 | -------------------------------------------------------------------------------- /examples/fluxible-router/actions/updateTime.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | export default function (context, payload, done) { 6 | context.dispatch('UPDATE_TIME'); 7 | done(); 8 | } 9 | -------------------------------------------------------------------------------- /examples/doc-site/configs/redirects.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | '/guides/bringing-flux-to-the-server.html': 3 | '/blog/2014-11-06-bringing-flux-to-the-server.html', 4 | '/tutorials/routing.html': '/extensions/routing.html', 5 | '/guides/data-services.html': '/extensions/data-services.html', 6 | }; 7 | -------------------------------------------------------------------------------- /examples/fluxible-router/components/Home.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import React from 'react'; 6 | 7 | const Home = () =>

Welcome to the site!

; 8 | 9 | export default Home; 10 | -------------------------------------------------------------------------------- /examples/fluxible-router/components/About.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import React from 'react'; 6 | 7 | const About = () =>

This is a description of the site.

; 8 | 9 | export default About; 10 | -------------------------------------------------------------------------------- /packages/fluxible/addons/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | 7 | module.exports = { 8 | BaseStore: require('./BaseStore'), 9 | createStore: require('./createStore'), 10 | }; 11 | -------------------------------------------------------------------------------- /examples/react-router/actions/updateTime.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | 7 | module.exports = function (context, payload, done) { 8 | context.dispatch('UPDATE_TIME'); 9 | done(); 10 | }; 11 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.1.1/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "master", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /packages/fluxible-router/src/NavLink.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import createNavLinkComponent from './createNavLinkComponent'; 6 | 7 | const NavLink = createNavLinkComponent(); 8 | 9 | export default NavLink; 10 | -------------------------------------------------------------------------------- /examples/doc-site/tests/fixtures/doc-response.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 6 | export default { 7 | content: '

Quick Start

', 8 | key: '/docs/quick-start.md', 9 | title: 'Quick Start', 10 | }; 11 | -------------------------------------------------------------------------------- /examples/doc-site/utils/getSearchIndexPath.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export default function getSearchIndexPath() { 4 | let path = process.cwd() + '/build/search.json'; 5 | if (process.env.manhattan_context__cache_dir) { 6 | path = 7 | process.env.manhattan_context__cache_dir + '/fluxible.search.json'; 8 | } 9 | return path; 10 | } 11 | -------------------------------------------------------------------------------- /examples/doc-site/start.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 6 | // this file is mainly used to register babel 7 | // since the file that registers babel cannot be es6-ified 8 | 9 | require('@babel/register'); 10 | 11 | module.exports = require('./server'); 12 | -------------------------------------------------------------------------------- /examples/minimal/src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { provideContext } from 'fluxible-addons-react'; 3 | import RandomNumberGenerator from './RandomNumberGenerator'; 4 | 5 | const App = () => ( 6 |
7 |

Fluxible Minimal Example

8 | 9 |
10 | ); 11 | 12 | export default provideContext(App); 13 | -------------------------------------------------------------------------------- /examples/react-router/components/Home.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import React from 'react'; 6 | 7 | class Home extends React.Component { 8 | render() { 9 | return

Welcome to the site!

; 10 | } 11 | } 12 | 13 | export default Home; 14 | -------------------------------------------------------------------------------- /packages/fluxible-router/.babelrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [["@babel/plugin-transform-runtime", { "version": "7.14.0" }]], 3 | "env": { 4 | "commonjs": { 5 | "presets": [["@babel/preset-env", { "modules": "commonjs" }]] 6 | }, 7 | "es": { 8 | "presets": [["@babel/preset-env", { "modules": false }]] 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/create-react-app/src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { provideContext } from 'fluxible-addons-react'; 3 | import RandomNumberGenerator from './RandomNumberGenerator'; 4 | 5 | const App = () => ( 6 |
7 |

Fluxible Minimal Example

8 | 9 |
10 | ); 11 | 12 | export default provideContext(App); 13 | -------------------------------------------------------------------------------- /examples/doc-site/secrets.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This is a sample file for using your Github access token to collect 3 | * the doc's from the fluxible repo. 4 | * 5 | * GitHub Auth docs: https://docs.github.com/en/rest/overview/resources-in-the-rest-api#authentication 6 | */ 7 | export default { 8 | github: { 9 | accessToken: process.env.GITHUB_ACCESS_TOKEN || '', 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /examples/stale-props/src/actions.js: -------------------------------------------------------------------------------- 1 | import generateUUID from 'fluxible/utils/generateUUID'; 2 | 3 | export function addItem({ dispatch }, { label }) { 4 | dispatch('addItem', { 5 | id: generateUUID(), 6 | label, 7 | }); 8 | } 9 | 10 | export function removeItem({ dispatch }, { itemId }) { 11 | dispatch('removeItem', { 12 | itemId, 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /examples/react-router/components/About.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import React from 'react'; 6 | 7 | class About extends React.Component { 8 | render() { 9 | return

This is a description of the site.

; 10 | } 11 | } 12 | 13 | export default About; 14 | -------------------------------------------------------------------------------- /examples/create-react-app/src/index.js: -------------------------------------------------------------------------------- 1 | import ReactDOM from 'react-dom'; 2 | import { createElementWithContext } from 'fluxible-addons-react'; 3 | import fluxibleApp from './fluxibleApp'; 4 | 5 | const context = fluxibleApp.createContext(); 6 | const element = createElementWithContext(context); 7 | const rootElement = document.getElementById('root'); 8 | 9 | ReactDOM.render(element, rootElement); 10 | -------------------------------------------------------------------------------- /packages/fluxible-plugin-devtools/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | module.exports = require('./dist/lib/devtools-plugin').default; 6 | module.exports.Actions = require('./dist/components/Actions').default; 7 | module.exports.ActionTree = require('./dist/components/ActionTree').default; 8 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing Code to `fluxible` 2 | ------------------------------- 3 | 4 | Please be sure to read our [CLA][] before you submit pull requests or otherwise contribute to `fluxible`. This protects developers, who rely on [BSD license][]. 5 | 6 | [BSD license]: https://github.com/yahoo/fluxible/blob/master/LICENSE.md 7 | [CLA]: https://github.com/yahoo/.github/blob/master/PULL_REQUEST_TEMPLATE.md 8 | -------------------------------------------------------------------------------- /examples/doc-site/actions/doSearch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 6 | import debugLib from 'debug'; 7 | const debug = debugLib('doSearch'); 8 | 9 | export default function doSearch(context, query, done) { 10 | debug(query); 11 | context.dispatch('DO_SEARCH', query); 12 | done(); 13 | } 14 | -------------------------------------------------------------------------------- /examples/todo/README.md: -------------------------------------------------------------------------------- 1 | # todo 2 | 3 | This shows the full Flux flow from server to client as well as XHR 4 | posts for creating new todos so that they are persisted between page 5 | loads. 6 | 7 | ## Usage 8 | 9 | 10 | ```bash 11 | npm install 12 | npm run dev 13 | ``` 14 | 15 | This will use `nodemon` and `webpack` to watch for changes and restart 16 | and rebuild as needed. 17 | 18 | Open http://localhost:3000 19 | -------------------------------------------------------------------------------- /examples/minimal/babel.config.js: -------------------------------------------------------------------------------- 1 | const isNodeTarget = (api) => 2 | api.caller((caller) => caller && caller.target === 'node'); 3 | 4 | module.exports = (api) => ({ 5 | presets: [ 6 | [ 7 | '@babel/preset-env', 8 | { 9 | targets: isNodeTarget(api) ? { node: 'current' } : 'defaults', 10 | }, 11 | ], 12 | '@babel/preset-react', 13 | ], 14 | }); 15 | -------------------------------------------------------------------------------- /examples/minimal/src/AppStore.js: -------------------------------------------------------------------------------- 1 | import { createReducerStore } from 'fluxible-reducer-store'; 2 | 3 | const AppStore = createReducerStore({ 4 | storeName: 'AppStore', 5 | initialState: { number: 0 }, 6 | reducers: { 7 | SET_NUMBER: (state, { number }) => ({ ...state, number }), 8 | }, 9 | getters: { 10 | getNumber: ({ number }) => number, 11 | }, 12 | }); 13 | 14 | export default AppStore; 15 | -------------------------------------------------------------------------------- /examples/create-react-app/src/AppStore.js: -------------------------------------------------------------------------------- 1 | import { createReducerStore } from 'fluxible-reducer-store'; 2 | 3 | const AppStore = createReducerStore({ 4 | storeName: 'AppStore', 5 | initialState: { number: 0 }, 6 | reducers: { 7 | SET_NUMBER: (state, { number }) => ({ ...state, number }), 8 | }, 9 | getters: { 10 | getNumber: ({ number }) => number, 11 | }, 12 | }); 13 | 14 | export default AppStore; 15 | -------------------------------------------------------------------------------- /examples/create-react-app/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /packages/fluxible-addons-react/docs/api/useFluxible.md: -------------------------------------------------------------------------------- 1 | # useFluxible 2 | 3 | ```js 4 | import { useFluxible } from 'fluxible-addons-react'; 5 | ``` 6 | 7 | `useFluxible` is a React hook that returns the Fluxible component 8 | context. 9 | 10 | ## Example 11 | 12 | ```js 13 | const Component = () => { 14 | const { executeAction } = useFluxible(); 15 | 16 | return 20 | 21 | ); 22 | }; 23 | 24 | export default Input; 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /examples/todo/actions/updateTodo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | 7 | module.exports = function (context, payload, done) { 8 | var todo = payload; 9 | todo.pending = true; 10 | 11 | context.dispatch('UPDATE_TODO_START', todo); 12 | 13 | context.service.update('todo', todo, {}, function (err, theTodo) { 14 | if (err) { 15 | context.dispatch('UPDATE_TODO_FAILURE', todo); 16 | done(); 17 | return; 18 | } 19 | 20 | context.dispatch('UPDATE_TODO_SUCCESS', theTodo); 21 | done(); 22 | }); 23 | }; 24 | -------------------------------------------------------------------------------- /examples/todo/actions/showTodos.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | 7 | module.exports = function (context, payload, done) { 8 | context.dispatch('RECEIVE_TODOS_START', payload); 9 | context.dispatch('UPDATE_PAGE_TITLE', 'showTodos | flux-examples'); 10 | 11 | context.service.read('todo', {}, {}, function (err, todos) { 12 | if (err) { 13 | context.dispatch('RECEIVE_TODOS_FAILURE', payload); 14 | done(); 15 | return; 16 | } 17 | context.dispatch('RECEIVE_TODOS_SUCCESS', todos); 18 | done(); 19 | }); 20 | }; 21 | -------------------------------------------------------------------------------- /packages/fluxible-plugin-devtools/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## 0.1.8 4 | 5 | * [#717] refactor: remove debug dependency from all packages 6 | 7 | ## 0.1.5 8 | 9 | * [#460] Fix to devtools-plugin to support Actions without a "callback" param (@carystanley) 10 | 11 | ## 0.1.4 12 | 13 | * [#445] Show start time stamp 14 | 15 | ## 0.1.3 16 | 17 | * [#432] Ability to inspect dispatch calls as well as action/dispatch payloads 18 | * [#433] Fix Readme (@ali1k) 19 | 20 | ## 0.1.2 21 | 22 | ### Bug Fixes 23 | 24 | * [#431] Always load d3, even if user loaded another version of d3. 25 | 26 | ## 0.1.1 27 | 28 | ### Bug Fixes 29 | 30 | * [#425] Fix d3 key function 31 | 32 | ## 0.1.0 33 | 34 | * Initial commit 35 | -------------------------------------------------------------------------------- /packages/fluxible-router/docs/guides/scrolling.md: -------------------------------------------------------------------------------- 1 | # Scroll Position Management 2 | 3 | [`handleHistory`](../api/handleHistory.md) has a built-in mechanism for managing scroll position upon page navigation, for modern browsers that support native history state: 4 | 5 | * reset scroll position to `(0, 0)` when user clicks on a link and navigates to a new page, and 6 | * restore scroll position to last visited state when user clicks forward and back buttons to navigate between pages. 7 | 8 | If you want to disable this behavior, you can set `enableScroll` option to `false` for [`handleHistory`](../api/handleHistory.md): 9 | 10 | ```js 11 | Application = handleHistory(Application, { 12 | enableScroll: false 13 | }); 14 | ``` 15 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2020: true, 5 | jest: true, 6 | node: true, 7 | }, 8 | extends: ['eslint:recommended', 'plugin:react/recommended'], 9 | parserOptions: { 10 | sourceType: 'module', 11 | ecmaFeatures: { 12 | jsx: true, 13 | }, 14 | }, 15 | plugins: ['react'], 16 | rules: { 17 | 'no-console': 0, 18 | 'no-empty': 0, 19 | 'no-prototype-builtins': 0, 20 | 'no-redeclare': 0, 21 | 'no-unused-vars': 0, 22 | }, 23 | settings: { 24 | react: { 25 | pragma: 'React', 26 | version: '16.0', 27 | }, 28 | }, 29 | }; 30 | -------------------------------------------------------------------------------- /examples/react-router/components/Timestamp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import React from 'react'; 6 | import updateTime from '../actions/updateTime'; 7 | import TimeStore from '../stores/TimeStore'; 8 | import { connectToStores } from 'fluxible-addons-react'; 9 | 10 | const Timestamp = (props) => ( 11 | 12 | {props.time} 13 | 14 | ); 15 | 16 | export default connectToStores(Timestamp, [TimeStore], (context) => ({ 17 | ...context.getStore(TimeStore).getState(), 18 | onClick: () => context.executeAction(updateTime), 19 | })); 20 | -------------------------------------------------------------------------------- /examples/chat/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | mode: 'development', 5 | entry: './client.js', 6 | output: { 7 | path: path.resolve('./build/js'), 8 | filename: 'client.js', 9 | publicPath: '/public/js/', 10 | }, 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.(js|jsx)$/, 15 | exclude: /node_modules/, 16 | use: { loader: 'babel-loader' }, 17 | }, 18 | ], 19 | }, 20 | devServer: { 21 | historyApiFallback: true, 22 | port: 3000, 23 | proxy: { 24 | '*': { target: 'http://localhost:3001' }, 25 | }, 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /examples/todo/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | mode: 'development', 5 | entry: './client.js', 6 | output: { 7 | path: path.resolve('./build/js'), 8 | filename: 'client.js', 9 | publicPath: '/public/js/', 10 | }, 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.(js|jsx)$/, 15 | exclude: /node_modules/, 16 | use: { loader: 'babel-loader' }, 17 | }, 18 | ], 19 | }, 20 | devServer: { 21 | historyApiFallback: true, 22 | port: 3000, 23 | proxy: { 24 | '*': { target: 'http://localhost:3001' }, 25 | }, 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /examples/doc-site/actions/loadIndex.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 6 | import debugLib from 'debug'; 7 | const debug = debugLib('loadIndex'); 8 | 9 | function loadIndex(context, payload, done) { 10 | debug(payload); 11 | 12 | // Load from service 13 | context.service.read('search', {}, {}, function (err, data) { 14 | if (err) { 15 | done(err); 16 | return; 17 | } 18 | debug('get index from service'); 19 | context.dispatch('RECEIVE_INDEX', data); 20 | done(); 21 | }); 22 | } 23 | loadIndex.displayName = 'loadIndex'; 24 | export default loadIndex; 25 | -------------------------------------------------------------------------------- /examples/react-router/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | mode: 'development', 5 | entry: './client.js', 6 | output: { 7 | path: path.resolve('./build/js'), 8 | filename: 'client.js', 9 | publicPath: '/public/js/', 10 | }, 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.(js|jsx)$/, 15 | exclude: /node_modules/, 16 | use: { loader: 'babel-loader' }, 17 | }, 18 | ], 19 | }, 20 | devServer: { 21 | historyApiFallback: true, 22 | port: 3000, 23 | proxy: { 24 | '*': { target: 'http://localhost:3001' }, 25 | }, 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /packages/dispatchr/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # dispatchr 2 | 3 | ## 1.2.1 4 | 5 | ### Patch Changes 6 | 7 | * [#717] refactor: remove debug dependency from all packages 8 | 9 | ## 1.2.0 10 | 11 | ### Minor Changes 12 | 13 | * [#536] Use errorHandler for exceptions thrown inside stores by @ash14 14 | 15 | ## 1.1.1 16 | 17 | ### Patch Changes 18 | 19 | * [#519] Throw correct 'store has no method' error by @ash14 20 | 21 | ## 1.1.0 22 | 23 | ### Minor Changes 24 | 25 | * [#496] Allow error handler to be used instead of throwing. [Docs](https://github.com/yahoo/fluxible/blob/master/packages/dispatchr/docs/dispatchr.md#error-handling). 26 | 27 | ## 1.0.3 28 | 29 | ### Patch Changes 30 | 31 | * [#479] Update eventemitter3 to 2.0.0, by @stanback 32 | -------------------------------------------------------------------------------- /packages/fluxible-addons-react/src/FluxibleComponent.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import { cloneElement, createElement } from 'react'; 6 | import { object, node } from 'prop-types'; 7 | import FluxibleProvider from './FluxibleProvider'; 8 | 9 | const FluxibleComponent = ({ children, context }) => { 10 | const childrenWithContext = cloneElement(children, { context }); 11 | return createElement(FluxibleProvider, { context }, childrenWithContext); 12 | }; 13 | 14 | FluxibleComponent.propTypes = { 15 | children: node.isRequired, 16 | context: object.isRequired, 17 | }; 18 | 19 | export default FluxibleComponent; 20 | -------------------------------------------------------------------------------- /examples/fluxible-router/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | mode: 'development', 5 | entry: './client.js', 6 | output: { 7 | path: path.resolve('./build/js'), 8 | filename: 'client.js', 9 | publicPath: '/public/js/', 10 | }, 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.(js|jsx)$/, 15 | exclude: /node_modules/, 16 | use: { loader: 'babel-loader' }, 17 | }, 18 | ], 19 | }, 20 | devServer: { 21 | historyApiFallback: true, 22 | port: 3000, 23 | proxy: { 24 | '*': { target: 'http://localhost:3001' }, 25 | }, 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /examples/todo/client.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | /*global document, window */ 6 | 'use strict'; 7 | const ReactDOM = require('react-dom'); 8 | const app = require('./app'); 9 | const { createElementWithContext } = require('fluxible-addons-react'); 10 | 11 | const dehydratedState = window.App; // sent from the server 12 | 13 | app.rehydrate(dehydratedState, function (err, context) { 14 | if (err) { 15 | throw err; 16 | } 17 | 18 | window.context = context; 19 | 20 | const mountNode = document.getElementById('todoapp'); 21 | 22 | ReactDOM.hydrate(createElementWithContext(context), mountNode); 23 | }); 24 | -------------------------------------------------------------------------------- /examples/minimal/src/RandomNumberGenerator.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connectToStores } from 'fluxible-addons-react'; 3 | import AppStore from './AppStore'; 4 | import * as actions from './actions'; 5 | 6 | const RandomNumberGenerator = ({ number, setRandomNumber }) => ( 7 |
8 |

9 | Number: {number} 10 |

11 | 12 |
13 | ); 14 | 15 | export default connectToStores( 16 | RandomNumberGenerator, 17 | [AppStore], 18 | (context) => ({ 19 | number: context.getStore(AppStore).getNumber(), 20 | setRandomNumber: () => context.executeAction(actions.setRandomNumber), 21 | }), 22 | ); 23 | -------------------------------------------------------------------------------- /examples/create-react-app/src/RandomNumberGenerator.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connectToStores } from 'fluxible-addons-react'; 3 | import AppStore from './AppStore'; 4 | import * as actions from './actions'; 5 | 6 | const RandomNumberGenerator = ({ number, setRandomNumber }) => ( 7 |
8 |

9 | Number: {number} 10 |

11 | 12 |
13 | ); 14 | 15 | export default connectToStores( 16 | RandomNumberGenerator, 17 | [AppStore], 18 | (context) => ({ 19 | number: context.getStore(AppStore).getNumber(), 20 | setRandomNumber: () => context.executeAction(actions.setRandomNumber), 21 | }), 22 | ); 23 | -------------------------------------------------------------------------------- /examples/chat/app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | var React = require('react'); 7 | var Fluxible = require('fluxible'); 8 | var fetchrPlugin = require('fluxible-plugin-fetchr'); 9 | 10 | var app = new Fluxible({ 11 | component: require('./components/ChatApp'), 12 | }); 13 | 14 | app.plug( 15 | fetchrPlugin({ 16 | xhrPath: '/api', 17 | }), 18 | ); 19 | 20 | app.registerStore(require('./stores/RouteStore')); 21 | app.registerStore(require('./stores/MessageStore')); 22 | app.registerStore(require('./stores/ThreadStore')); 23 | app.registerStore(require('./stores/UnreadThreadStore')); 24 | 25 | module.exports = app; 26 | -------------------------------------------------------------------------------- /examples/todo/actions/toggleAll.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | 7 | module.exports = function (context, payload, done) { 8 | context.dispatch('TOGGLE_ALL_TODO_START', payload); 9 | 10 | context.service.update( 11 | 'todo.toggleAll', 12 | payload, 13 | {}, 14 | function (err, todos) { 15 | if (err) { 16 | context.dispatch('TOGGLE_ALL_TODO_FAILURE', payload); 17 | done(); 18 | return; 19 | } 20 | 21 | context.dispatch('TOGGLE_ALL_TODO_SUCCESS', todos); 22 | done(); 23 | }, 24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /examples/doc-site/utils/assets.js: -------------------------------------------------------------------------------- 1 | /** 2 | * In production, we use the webpack stats plugin to collect the asset hash names 3 | * and replace the local paths with the production ones. 4 | */ 5 | 6 | import path from 'path'; 7 | const CDN_PATH = '/public/js/'; 8 | 9 | let assets = { 10 | main: CDN_PATH + 'main.js', 11 | }; 12 | 13 | if ('production' === process.env.NODE_ENV) { 14 | try { 15 | var webpackAssets = require( 16 | path.join(__dirname, '..', 'build', 'assets.json'), 17 | ); 18 | } catch (e) { 19 | throw new Error( 20 | 'Please run `grunt build` to generate the production assets.', 21 | ); 22 | } 23 | assets.main = CDN_PATH + webpackAssets.assets.main; 24 | } 25 | 26 | export default assets; 27 | -------------------------------------------------------------------------------- /packages/fluxible-addons-react/docs/api/batchedUpdatePlugin.md: -------------------------------------------------------------------------------- 1 | # batchedUpdatePlugin 2 | 3 | ```js 4 | import { batchedUpdatePlugin } from 'fluxible-addons-react; 5 | ``` 6 | 7 | `batchedUpdatePlugin` is a Fluxible plugin that will batch React 8 | `setState` calls together when they are part of the same 9 | `dispatch`. This can improve performance as there will be fewer 10 | re-renders for components that listen to multiple stores that react to 11 | the same dispatch command. 12 | 13 | ## Example 14 | 15 | The plugin is added to Fluxible immediately after instantiation as 16 | follows: 17 | 18 | ```js 19 | const app = new Fluxible(); 20 | app.plug(batchedUpdatePlugin()); 21 | ``` 22 | 23 | This will wrap the `actionContext.dispatch` function with a call to 24 | `ReactDOM.unstable_batchedUpdates`. 25 | -------------------------------------------------------------------------------- /examples/doc-site/utils/renderer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 6 | import marked from 'marked'; 7 | const renderer = new marked.Renderer(); 8 | 9 | renderer.heading = function (text, level) { 10 | let escapedText = text.toLowerCase().replace(/[^\w]+/g, '-'); 11 | 12 | return ( 13 | '' + 16 | '' + 19 | text + 20 | ' ' + 21 | '#' + 24 | '' 27 | ); 28 | }; 29 | 30 | export default renderer; 31 | -------------------------------------------------------------------------------- /examples/chat/README.md: -------------------------------------------------------------------------------- 1 | # chat 2 | 3 | Ported from 4 | https://github.com/facebook/flux/tree/master/examples/flux-chat 5 | 6 | This shows the full Flux flow from server to client as well as XHR 7 | posts for creating new messages so that they are persisted between 8 | page loads. 9 | 10 | ## Usage 11 | 12 | ```bash 13 | npm install 14 | npm run dev 15 | ``` 16 | 17 | This will use `nodemon` and `webpack` to watch for changes and restart 18 | and rebuild as needed. 19 | 20 | Open http://localhost:3000 21 | 22 | This example also includes different patterns for render and loading data. 23 | * You can add `?load=0` to defer loading data until the client. A 24 | delay of 1 second is added on the client in order to make this more 25 | apparent. 26 | * You can add `?render=0` to defer rendering until the client. 27 | -------------------------------------------------------------------------------- /examples/fluxible-router/components/Timestamp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import React from 'react'; 6 | import updateTime from '../actions/updateTime'; 7 | import TimeStore from '../stores/TimeStore'; 8 | import { connectToStores } from 'fluxible-addons-react'; 9 | 10 | const Timestamp = ({ onClick, time }) => ( 11 | 12 | {time} 13 | 14 | ); 15 | 16 | export default connectToStores(Timestamp, [TimeStore], (context) => { 17 | const timeStore = context.getStore(TimeStore); 18 | const { time } = timeStore.getState(); 19 | const onClick = () => context.executeAction(updateTime); 20 | return { time, onClick }; 21 | }); 22 | -------------------------------------------------------------------------------- /packages/fluxible-addons-react/src/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | export { default as FluxibleComponent } from './FluxibleComponent'; 6 | export { default as FluxibleComponentContext } from './FluxibleComponentContext'; 7 | export { default as FluxibleProvider } from './FluxibleProvider'; 8 | export { default as batchedUpdatePlugin } from './batchedUpdatePlugin'; 9 | export { default as connectToStores } from './connectToStores'; 10 | export { default as createElementWithContext } from './createElementWithContext'; 11 | export { default as provideContext } from './provideContext'; 12 | export { default as useFluxible } from './useFluxible'; 13 | export { default as withFluxible } from './withFluxible'; 14 | -------------------------------------------------------------------------------- /examples/react-router/components/Page.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import React from 'react'; 6 | import PageStore from '../stores/PageStore'; 7 | import { connectToStores } from 'fluxible-addons-react'; 8 | 9 | class Page extends React.Component { 10 | static contextTypes = { 11 | getStore: React.PropTypes.func, 12 | executeAction: React.PropTypes.func, 13 | }; 14 | constructor(props, context) { 15 | super(props, context); 16 | } 17 | render() { 18 | return

{this.props.content}

; 19 | } 20 | } 21 | 22 | Page = connectToStores(Page, [PageStore], (context) => 23 | context.getStore(PageStore).getState(), 24 | ); 25 | 26 | export default Page; 27 | -------------------------------------------------------------------------------- /examples/doc-site/configs/atomic.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // COLORS: 3 | // redish: .C-f2438c 4 | // blueish: .C-07f 5 | breakPoints: { 6 | sm: '@media(min-width:700px)', 7 | md: '@media(min-width:992px)', 8 | lg: '@media(min-width:1200px)', 9 | }, 10 | // custom atomic classes mapped to their values 11 | custom: { 12 | 'Bdx(1)': '1px solid #ccc', 13 | 'Bd(1)': '1px solid rgba(2, 128, 174, .3)', 14 | 'Bdt(1)': '1px solid rgba(2, 128, 174, .3)', 15 | 'Bd(2)': '1px solid rgb(255, 255, 255)', 16 | 'Bdb(1)': '1px solid rgba(2, 128, 174, .3)', 17 | 'Bgc(logo)': '#0262AA', 18 | 'Bg(splash)': 19 | 'url("../images/splash_background.jpg") no-repeat #0262AA', 20 | 'Tsh(1)': '0 1px 0 rgba(0, 0, 0, 0.8)', 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /docs/quick-start.md: -------------------------------------------------------------------------------- 1 | # Quick Start 2 | 3 | ```bash 4 | npm install -g yo generator-fluxible 5 | ``` 6 | 7 | To use the generator, create a directory and cd into it. Then run `yo fluxible` which will create a working Fluxible application. To start the application, run `npm run dev`. View it in a browser at http://localhost:3000. 8 | 9 | ```bash 10 | mkdir example && cd example 11 | yo fluxible 12 | npm run dev 13 | ``` 14 | 15 | `open http://localhost:3000` 16 | 17 | This will generate a simple application that demonstrates the basics of using Fluxible: routing, store dehydration from server, and client rehydrating. 18 | 19 | From here, we recommend learning about [stores](../packages/fluxible/docs/api/Stores.md), [actions](../packages/fluxible/docs/api/Actions.md), and React integration with your [components](../packages/fluxible/docs/api/Components.md). 20 | -------------------------------------------------------------------------------- /examples/doc-site/services/search.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 6 | import debugLib from 'debug'; 7 | import fs from 'fs'; 8 | import getSearchIndexPath from '../utils/getSearchIndexPath'; 9 | import { getDocuments, getLunrIndex } from './docs'; 10 | const debug = debugLib('SearchService'); 11 | 12 | export default { 13 | name: 'search', 14 | read: function (req, resource, params, config, callback) { 15 | debug('Reading index'); 16 | try { 17 | debug('Index loaded'); 18 | return callback(null, { 19 | docs: getDocuments(), 20 | index: getLunrIndex().toJSON(), 21 | }); 22 | } catch (e) { 23 | callback(e); 24 | } 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /packages/fluxible-plugin-devtools/src/components/Actions.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import PropTypes from 'prop-types'; 6 | import React from 'react'; 7 | import ActionTree from './ActionTree'; 8 | 9 | export default class Actions extends React.Component { 10 | static contextTypes = { 11 | devtools: PropTypes.object, 12 | }; 13 | 14 | render() { 15 | var actions = this.context.devtools 16 | .getActionHistory() 17 | .map((action) => ( 18 | 23 | )); 24 | return
{actions}
; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/fluxible-plugin-fetchr/tests/fixtures/services/mockService.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | module.exports = { 6 | resource: 'test', 7 | read: function read(req, resource, params, config, callback) { 8 | callback(null, 'read', { 9 | headers: { 10 | 'Cache-Control': 'private', 11 | }, 12 | }); 13 | }, 14 | create: function create(req, resource, params, config, body, callback) { 15 | callback(null, 'create'); 16 | }, 17 | update: function update(req, resource, params, config, body, callback) { 18 | callback(null, 'update'); 19 | }, 20 | delete: function del(req, resource, params, config, callback) { 21 | callback(null, 'delete'); 22 | }, 23 | }; 24 | -------------------------------------------------------------------------------- /examples/stale-props/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "stale-props", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.11.4", 7 | "@testing-library/react": "^11.1.0", 8 | "@testing-library/user-event": "^12.1.10", 9 | "fluxible": "^1.4.2", 10 | "fluxible-addons-react": "^1.0.0", 11 | "react": "^17.0.2", 12 | "react-dom": "^17.0.2", 13 | "react-scripts": "4.0.3", 14 | "web-vitals": "^1.0.1" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start", 18 | "build": "react-scripts build", 19 | "test": "react-scripts test", 20 | "eject": "react-scripts eject" 21 | }, 22 | "eslintConfig": { 23 | "extends": [ 24 | "react-app", 25 | "react-app/jest" 26 | ] 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/todo/actions/createTodo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | var TodoStore = require('../stores/TodoStore'); 7 | 8 | module.exports = function (context, payload, done) { 9 | var todoStore = context.getStore(TodoStore); 10 | var newTodo = todoStore.createTodo({ 11 | timestamp: Date.now(), 12 | text: payload.text, 13 | }); 14 | 15 | context.dispatch('CREATE_TODO_START', newTodo); 16 | 17 | context.service.create('todo', newTodo, {}, function (err, todo) { 18 | if (err) { 19 | context.dispatch('CREATE_TODO_FAILURE', newTodo); 20 | done(); 21 | return; 22 | } 23 | 24 | context.dispatch('CREATE_TODO_SUCCESS', todo); 25 | done(); 26 | }); 27 | }; 28 | -------------------------------------------------------------------------------- /packages/fluxible-router/docs/api/createNavLinkComponent.md: -------------------------------------------------------------------------------- 1 | # createNavLinkComponent 2 | 3 | `createNavLinkComponent` is a function for you to create a NavLink component, you are able to pass options to overwrite attributes to generate the NavLink. e.g., custom mixin or click handler. 4 | 5 | ## Parameters 6 | 7 | | Param Name | Param Type | Description | 8 | |-----------|-----------|-------------| 9 | | overwriteSpec | Object | the spec object taken to overwrite the default spec when we create NavLink using React.createClass | 10 | 11 | 12 | ## Example Usage 13 | 14 | ```js 15 | import { createNavLinkComponent } from 'fluxible-router'; 16 | 17 | export default createNavLinkComponent({ 18 | displayName: 'CustomNavLink', 19 | mixins: [someMixin], 20 | clickHandler: function (e) { 21 | // custom click handler 22 | this.dispatchNavAction(e); 23 | } 24 | }); 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Docs 2 | 3 | If you want to jump right into building your application, head over to our [Quick Start Guide](quick-start.md). 4 | 5 | If you want to look at example applications, check out our examples: 6 | 7 | - [Chat](https://github.com/yahoo/fluxible/blob/master/examples/chat) - Port of [Facebook's Flux chat example](https://github.com/facebook/flux/tree/master/examples/). 8 | - [Fluxible Router](https://github.com/yahoo/fluxible/blob/master/examples/fluxible-router) - Simple isomorphic routing in Flux flow. 9 | - [React Router](https://github.com/yahoo/fluxible/blob/master/examples/react-router) - Simple isomorphic routing with React router. 10 | - [TodoMVC](https://github.com/yahoo/fluxible/blob/master/examples/todo) - [TodoMVC](https://github.com/tastejs/todomvc) example using Fluxible. 11 | 12 | Or check out some [community applications](community/reference-applications.md). 13 | -------------------------------------------------------------------------------- /examples/doc-site/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es6: true, 5 | mocha: true, 6 | node: true, 7 | }, 8 | extends: ['eslint:recommended', 'plugin:react/recommended'], 9 | parser: 'babel-eslint', 10 | parserOptions: { 11 | ecmaFeatures: { 12 | jsx: true, 13 | }, 14 | }, 15 | plugins: ['react'], 16 | rules: { 17 | 'no-class-assign': 0, 18 | 'no-console': 0, 19 | 'no-empty': 0, 20 | 'no-redeclare': 0, 21 | 'no-unused-vars': 0, 22 | 'react/no-find-dom-node': 0, 23 | 'react/no-string-refs': 0, 24 | 'react/no-unescaped-entities': 0, 25 | 'react/prop-types': 0, 26 | }, 27 | settings: { 28 | react: { 29 | pragma: 'React', 30 | version: '16.0', 31 | }, 32 | }, 33 | }; 34 | -------------------------------------------------------------------------------- /packages/fluxible-addons-react/docs/api/createElementWithContext.md: -------------------------------------------------------------------------------- 1 | # createElementWithContext(context, props) 2 | 3 | ```js 4 | import { createElementWithContext } from 'fluxible-addons-react; 5 | ``` 6 | 7 | Convenience method for instantiating the Fluxible app's top level 8 | React component (if provided in the constructor) with the given props 9 | with an additional `context` key containing the Fluxible component 10 | context. 11 | 12 | ```js 13 | const app = new Fluxible({ 14 | component: MyComponent 15 | }); 16 | const context = app.createContext(); 17 | const markup = ReactDOM.renderToString(createElementWithContext(context, props)); 18 | ``` 19 | 20 | This is the same as the following: 21 | 22 | ```js 23 | const markup = ReactDOM.renderToString( 24 | 25 | 26 | 27 | ); 28 | ``` 29 | -------------------------------------------------------------------------------- /examples/chat/actions/openThread.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | var debug = require('debug')('Example:openThreadAction'); 7 | var ThreadStore = require('../stores/ThreadStore'); 8 | 9 | module.exports = function (context, payload, done) { 10 | debug('dispatching OPEN_THREAD', payload); 11 | 12 | /* If thread Id isn't provided make it the latest thread. 13 | * Called if page loaded at root (/) 14 | */ 15 | if (!payload.threadID) { 16 | debug('opening most recent thread'); 17 | var threadStore = context.getStore(ThreadStore); 18 | var allChrono = threadStore.getAllChrono(); 19 | payload.threadID = allChrono[allChrono.length - 1].id; 20 | } 21 | 22 | context.dispatch('OPEN_THREAD', payload); 23 | done(); 24 | }; 25 | -------------------------------------------------------------------------------- /examples/doc-site/tests/unit/actions/demoException.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | /* global describe, it, beforeEach */ 6 | 'use strict'; 7 | import { expect } from 'chai'; 8 | import { createMockActionContext } from 'fluxible/utils'; 9 | import demoException from '../../../actions/demoException'; 10 | 11 | describe('site', () => { 12 | describe('demo exception', function () { 13 | let context; 14 | 15 | beforeEach(function () { 16 | context = createMockActionContext(); 17 | }); 18 | 19 | it('should execute the action', function (done) { 20 | demoException(context, {}, function (err) { 21 | expect(err).to.eql(new Error('Whoops!')); 22 | done(); 23 | }); 24 | }); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /examples/fluxible-router/README.md: -------------------------------------------------------------------------------- 1 | # routing with fluxible 2 | 3 | This shows routing on the client and the server with 4 | Fluxible. Navigation uses history pushes on the 5 | client but browser refresh will render the current page correctly on 6 | the server. 7 | 8 | ## Usage 9 | 10 | ```bash 11 | npm install 12 | npm run dev 13 | ``` 14 | 15 | This will use `nodemon` and `webpack` to watch for changes and restart 16 | and rebuild as needed. 17 | 18 | Open http://localhost:3000 19 | 20 | ### Browser-only setup 21 | 22 | It is possible to use fluxible and fluxible-router in browser-only 23 | enviroment. To run the example in browser-only enviroment install npm 24 | modules and run following command from fluxible-router directory 25 | 26 | ```bash 27 | npm run dev-browser 28 | ``` 29 | 30 | Open http://localhost:3000 31 | 32 | Directory `fluxible-router/browser-only` contains files, required for 33 | browser-only setup. 34 | -------------------------------------------------------------------------------- /examples/fluxible-router/browser-only/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | 4 | module.exports = { 5 | mode: 'development', 6 | entry: './browser-only.js', 7 | output: { 8 | path: path.resolve('./build/js'), 9 | filename: 'browser-only.js', 10 | publicPath: '/public/js/', 11 | }, 12 | module: { 13 | rules: [ 14 | { 15 | test: /\.(js|jsx)$/, 16 | exclude: /node_modules/, 17 | use: { 18 | loader: 'babel-loader', 19 | options: { 20 | rootMode: 'upward', 21 | }, 22 | }, 23 | }, 24 | ], 25 | }, 26 | plugins: [new HtmlWebpackPlugin()], 27 | devServer: { 28 | historyApiFallback: true, 29 | port: 3000, 30 | }, 31 | }; 32 | -------------------------------------------------------------------------------- /packages/fluxible-reducer-store/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fluxible-reducer-store", 3 | "version": "0.1.0", 4 | "description": "Reducer store for Fluxible", 5 | "main": "index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/yahoo/fluxible" 9 | }, 10 | "scripts": { 11 | "test": "../../node_modules/.bin/jest", 12 | "cover": "../../node_modules/.bin/jest --coverage", 13 | "lint": "../../node_modules/.bin/eslint *.js" 14 | }, 15 | "dependencies": { 16 | "fluxible": ">0.3.0" 17 | }, 18 | "author": "Michael Ridgway ", 19 | "contributors": [], 20 | "licenses": [ 21 | { 22 | "type": "BSD-3-Clause", 23 | "url": "https://github.com/yahoo/fluxible/blob/master/LICENSE.md" 24 | } 25 | ], 26 | "keywords": [ 27 | "yahoo", 28 | "flux", 29 | "react", 30 | "fluxible", 31 | "isomorphic", 32 | "reducer" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /packages/fluxible/utils/createMockActionContext.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | 7 | var dispatchr = require('dispatchr'); 8 | var MockActionContextClass = require('./MockActionContext'); 9 | 10 | module.exports = function createMockActionContext(options) { 11 | options = options || {}; 12 | options.mockActionContextClass = 13 | options.mockActionContextClass || MockActionContextClass; 14 | options.stores = options.stores || []; 15 | options.dispatcher = 16 | options.dispatcher || 17 | dispatchr.createDispatcher({ 18 | stores: options.stores, 19 | }); 20 | options.dispatcherContext = 21 | options.dispatcherContext || options.dispatcher.createContext(); 22 | 23 | return new options.mockActionContextClass(options.dispatcherContext); 24 | }; 25 | -------------------------------------------------------------------------------- /packages/dispatchr/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dispatchr", 3 | "version": "1.3.0", 4 | "description": "A Flux dispatcher for applications that run on the server and the client.", 5 | "main": "index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git://github.com/yahoo/fluxible.git" 9 | }, 10 | "scripts": { 11 | "test": "../../node_modules/.bin/jest", 12 | "cover": "../../node_modules/.bin/jest --coverage", 13 | "lint": "../../node_modules/.bin/eslint lib/ addons/ utils/ index.js" 14 | }, 15 | "author": "Michael Ridgway ", 16 | "licenses": [ 17 | { 18 | "type": "BSD-3-Clause", 19 | "url": "https://github.com/yahoo/fluxible/blob/master/LICENSE.md" 20 | } 21 | ], 22 | "dependencies": { 23 | "eventemitter3": "^4.0.7", 24 | "inherits": "^2.0.4" 25 | }, 26 | "keywords": [ 27 | "yahoo", 28 | "flux", 29 | "react", 30 | "dispatcher" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /examples/todo/stores/PageStore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | var createStore = require('fluxible/addons').createStore; 7 | 8 | var PageStore = createStore({ 9 | storeName: 'PageStore', 10 | handlers: { 11 | UPDATE_PAGE_TITLE: 'updatePageTitle', 12 | }, 13 | initialize: function () { 14 | this.pageTitle = ''; 15 | }, 16 | updatePageTitle: function (title) { 17 | this.pageTitle = title; 18 | this.emitChange(); 19 | }, 20 | getPageTitle: function () { 21 | return this.pageTitle; 22 | }, 23 | dehydrate: function () { 24 | return { 25 | pageTitle: this.pageTitle, 26 | }; 27 | }, 28 | rehydrate: function (state) { 29 | this.pageTitle = state.pageTitle; 30 | }, 31 | }); 32 | 33 | module.exports = PageStore; 34 | -------------------------------------------------------------------------------- /packages/fluxible/docs/api/addons/createStore.md: -------------------------------------------------------------------------------- 1 | # createStore 2 | 3 | ```js 4 | import createStore from 'fluxible/addons/createStore'; 5 | ``` 6 | 7 | A helper method similar to `React.createClass` but for creating stores that extend [`BaseStore`](BaseStore.md). Also supports mixins. 8 | 9 | ## Example 10 | 11 | ```js 12 | export default createStore({ 13 | storeName: 'ApplicationStore', 14 | handlers: { 15 | 'RECEIVE_PAGE': 'handleReceivePage' 16 | }, 17 | handleReceivePage: function (payload) { 18 | this.currentPageName = payload.pageName; 19 | this.emitChange(); 20 | }, 21 | getCurrentPage: function () { 22 | return this.currentPageName; 23 | }, 24 | dehydrate: function () { 25 | return { 26 | currentPageName: this.currentPageName 27 | }; 28 | }, 29 | rehydrate: function (state) { 30 | this.currentPageName = state.currentPageName; 31 | } 32 | }); 33 | ``` 34 | -------------------------------------------------------------------------------- /packages/fluxible/utils/createMockComponentContext.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | 7 | var dispatchr = require('dispatchr'); 8 | var MockComponentContextClass = require('./MockComponentContext'); 9 | 10 | module.exports = function createMockComponentContext(options) { 11 | options = options || {}; 12 | options.mockComponentContextClass = 13 | options.mockComponentContextClass || MockComponentContextClass; 14 | options.stores = options.stores || []; 15 | options.dispatcher = 16 | options.dispatcher || 17 | dispatchr.createDispatcher({ 18 | stores: options.stores, 19 | }); 20 | options.dispatcherContext = 21 | options.dispatcherContext || options.dispatcher.createContext(); 22 | 23 | return new options.mockComponentContextClass(options.dispatcherContext); 24 | }; 25 | -------------------------------------------------------------------------------- /examples/doc-site/client.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | /*global document, window */ 6 | 7 | import React from 'react'; 8 | import { render } from 'react-dom'; 9 | import app from './app'; 10 | import Debug from 'debug'; 11 | import { 12 | batchedUpdatePlugin, 13 | createElementWithContext, 14 | } from 'fluxible-addons-react'; 15 | 16 | // Add batched update plugin on client only 17 | app.plug(batchedUpdatePlugin()); 18 | 19 | const dehydratedState = window.App; // sent from the server 20 | 21 | window.app = app; 22 | window.fluxibleDebug = Debug; 23 | 24 | app.rehydrate(dehydratedState, function (err, context) { 25 | if (err) { 26 | throw err; 27 | } 28 | 29 | window.context = context; 30 | 31 | render( 32 | createElementWithContext(context), 33 | document.getElementById('docsapp'), 34 | ); 35 | }); 36 | -------------------------------------------------------------------------------- /examples/fluxible-router/client.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | /*global App, document, window */ 6 | import ReactDOM from 'react-dom'; 7 | import debug from 'debug'; 8 | import app from './app'; 9 | import { createElementWithContext } from 'fluxible-addons-react'; 10 | 11 | const bootstrapDebug = debug('Example'); 12 | const dehydratedState = window.App; // Sent from the server 13 | 14 | bootstrapDebug('rehydrating app'); 15 | app.rehydrate(dehydratedState, function (err, context) { 16 | if (err) { 17 | throw err; 18 | } 19 | window.debug = debug; 20 | window.context = context; 21 | const mountNode = document.getElementById('app'); 22 | 23 | bootstrapDebug('React Rendering'); 24 | ReactDOM.hydrate(createElementWithContext(context), mountNode, () => { 25 | bootstrapDebug('React Rendered'); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /examples/fluxible-router/stores/PageStore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import { BaseStore } from 'fluxible/addons'; 6 | 7 | class PageStore extends BaseStore { 8 | constructor(dispatcher) { 9 | super(dispatcher); 10 | this.content = 'initial content...'; 11 | } 12 | handleContentChange(payload) { 13 | this.content = 'content for page with id ' + payload.id; 14 | this.emitChange(); 15 | } 16 | getState() { 17 | return { 18 | content: this.content, 19 | }; 20 | } 21 | dehydrate() { 22 | return this.getState(); 23 | } 24 | rehydrate(state) { 25 | this.content = state.content; 26 | } 27 | } 28 | 29 | PageStore.storeName = 'PageStore'; 30 | PageStore.handlers = { 31 | LOAD_PAGE: 'handleContentChange', 32 | }; 33 | 34 | export default PageStore; 35 | -------------------------------------------------------------------------------- /packages/generator-fluxible/README.md: -------------------------------------------------------------------------------- 1 | # generator-fluxible 2 | 3 | [![npm version](https://badge.fury.io/js/generator-fluxible.svg)](http://badge.fury.io/js/generator-fluxible) 4 | 5 | ## Getting Started 6 | 7 | ```bash 8 | npm install -g yo 9 | ``` 10 | 11 | To install generator-fluxible from npm, run: 12 | 13 | ```bash 14 | npm install -g generator-fluxible 15 | ``` 16 | 17 | Finally, initiate the generator: 18 | 19 | ```bash 20 | cd new-project 21 | yo fluxible 22 | ``` 23 | 24 | During development, execute `npm run dev` to initiate webpack-dev-server 25 | (with react-hot-loader support) and your application's server using nodemon. 26 | Browse to `http://localhost:3000` to see a very simple Fluxible site with 27 | server-side rendering and client-side navigation. When you change files, 28 | the server will be reloaded and the bundle will be rebuilt. 29 | 30 | For other environments, make sure your application is built using 31 | `npm run build` and then run `npm start`. 32 | -------------------------------------------------------------------------------- /examples/fluxible-router/stores/TimeStore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import { BaseStore } from 'fluxible/addons'; 6 | 7 | class TimeStore extends BaseStore { 8 | constructor(dispatcher) { 9 | super(dispatcher); 10 | this.time = new Date(); 11 | } 12 | handleTimeChange(payload) { 13 | this.time = new Date(); 14 | this.emitChange(); 15 | } 16 | getState() { 17 | return { 18 | time: this.time.toString(), 19 | }; 20 | } 21 | dehydrate() { 22 | return this.getState(); 23 | } 24 | rehydrate(state) { 25 | this.time = new Date(state.time); 26 | } 27 | } 28 | 29 | TimeStore.storeName = 'TimeStore'; 30 | TimeStore.handlers = { 31 | NAVIGATE_START: 'handleTimeChange', 32 | UPDATE_TIME: 'handleTimeChange', 33 | }; 34 | 35 | export default TimeStore; 36 | -------------------------------------------------------------------------------- /packages/fluxible-addons-react/src/batchedUpdatePlugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import { unstable_batchedUpdates } from 'react-dom'; 6 | 7 | function createBatchedUpdatePlugin() { 8 | /** 9 | * @class BatchedUpdatePlugin 10 | */ 11 | return { 12 | name: 'BatchedUpdatePlugin', 13 | 14 | plugContext() { 15 | return { 16 | plugActionContext(actionContext) { 17 | const oldDispatch = actionContext.dispatch; 18 | actionContext.dispatch = (...args) => { 19 | unstable_batchedUpdates(() => { 20 | oldDispatch.apply(actionContext, args); 21 | }); 22 | }; 23 | }, 24 | }; 25 | }, 26 | }; 27 | } 28 | 29 | export default createBatchedUpdatePlugin; 30 | -------------------------------------------------------------------------------- /examples/react-router/stores/PageStore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | var createStore = require('fluxible/addons').createStore; 7 | 8 | var PageStore = createStore({ 9 | storeName: 'PageStore', 10 | initialize: function () { 11 | this.content = 'initial content...'; 12 | }, 13 | handleContentChange: function (payload) { 14 | this.content = 'content for page with id ' + payload.id; 15 | this.emitChange(); 16 | }, 17 | handlers: { 18 | LOAD_PAGE: 'handleContentChange', 19 | }, 20 | getState: function () { 21 | return { 22 | content: this.content, 23 | }; 24 | }, 25 | dehydrate: function () { 26 | return this.getState(); 27 | }, 28 | rehydrate: function (state) { 29 | this.content = state.content; 30 | }, 31 | }); 32 | 33 | module.exports = PageStore; 34 | -------------------------------------------------------------------------------- /packages/fluxible/utils/deprecateComponent.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | 7 | var React = require('react'); 8 | 9 | /** 10 | * Deprecates a component by logging a warning message when used 11 | * @method deprecateComponent 12 | * @param {React.Component} Component component to wrap 13 | * @param {string} warningMessage Custom contextTypes to add 14 | * @returns {React.Component} 15 | */ 16 | module.exports = function deprecateComponent(Component, warningMessage) { 17 | var DeprecationComponent = React.createClass({ 18 | displayName: 'DeprecationComponent', 19 | 20 | componentDidMount: function () { 21 | console.warn(warningMessage); 22 | }, 23 | 24 | render: function () { 25 | return React.createElement(Component, this.props); 26 | }, 27 | }); 28 | 29 | return DeprecationComponent; 30 | }; 31 | -------------------------------------------------------------------------------- /packages/fluxible-plugin-fetchr/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fluxible-plugin-fetchr", 3 | "version": "0.5.1", 4 | "description": "A plugin for Fluxible applications to provide an isomorphic interface for RESTful services", 5 | "main": "index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git://github.com/yahoo/fluxible.git" 9 | }, 10 | "scripts": { 11 | "test": "../../node_modules/.bin/jest", 12 | "cover": "../../node_modules/.bin/jest --coverage", 13 | "lint": "../../node_modules/.bin/eslint lib/ tests/ utils/ index.js" 14 | }, 15 | "dependencies": { 16 | "fetchr": "^0.7.0" 17 | }, 18 | "author": "Michael Ridgway ", 19 | "contributors": [], 20 | "licenses": [ 21 | { 22 | "type": "BSD-3-Clause", 23 | "url": "https://github.com/yahoo/fluxible/blob/master/LICENSE.md" 24 | } 25 | ], 26 | "keywords": [ 27 | "yahoo", 28 | "flux", 29 | "react", 30 | "fluxible", 31 | "fetchr", 32 | "rest" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /packages/generator-fluxible/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generator-fluxible", 3 | "version": "2.0.0", 4 | "description": "Yeoman generator for Fluxible", 5 | "main": "app/index.js", 6 | "repository": "yahoo/fluxible", 7 | "author": { 8 | "name": "Seth Bertalotto", 9 | "email": "sbertal@yahoo-inc.com" 10 | }, 11 | "scripts": { 12 | "cover": "../../node_modules/.bin/jest --coverage", 13 | "lint": "../../node_modules/.bin/eslint app/ tests/", 14 | "test": "../../node_modules/.bin/jest" 15 | }, 16 | "precommit": [ 17 | "lint", 18 | "test" 19 | ], 20 | "files": [ 21 | "app" 22 | ], 23 | "keywords": [ 24 | "yeoman-generator", 25 | "flux", 26 | "react", 27 | "fluxible" 28 | ], 29 | "dependencies": { 30 | "chalk": "^4.0.0", 31 | "prop-types": "^15.7.2", 32 | "underscore.string": "^3.0.2", 33 | "yeoman-generator": "^5.7.0", 34 | "yo": "^4.0.0", 35 | "yosay": "^2.0.2" 36 | }, 37 | "peerDependencies": { 38 | "yo": "^4.0.0" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/dispatchr/tests/unit/addons/BaseStore.test.js: -------------------------------------------------------------------------------- 1 | /*globals describe,it */ 2 | 'use strict'; 3 | 4 | var BaseStore = require('../../../addons/BaseStore'); 5 | 6 | var contextMock = { 7 | dimensions: {}, 8 | }; 9 | var dispatcherMock = { 10 | getContext: function () { 11 | return contextMock; 12 | }, 13 | }; 14 | 15 | describe('BaseStore', function () { 16 | it('instantiates correctly', function () { 17 | var store = new BaseStore(dispatcherMock); 18 | expect(store.dispatcher).toBe(dispatcherMock); 19 | expect(store.getContext()).toBe(dispatcherMock.getContext()); 20 | }); 21 | 22 | it('allows listening for changes', function (done) { 23 | var store = new BaseStore(dispatcherMock); 24 | var payloadMock = { 25 | foo: 'bar', 26 | }; 27 | store.addChangeListener(function (payload) { 28 | expect(payload.foo).toBe('bar'); 29 | done(); 30 | }); 31 | store.emitChange(payloadMock); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /packages/fluxible/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fluxible", 3 | "version": "1.4.2", 4 | "description": "A pluggable container for isomorphic flux applications", 5 | "main": "index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/yahoo/fluxible" 9 | }, 10 | "scripts": { 11 | "test": "../../node_modules/.bin/jest", 12 | "cover": "../../node_modules/.bin/jest --coverage", 13 | "lint": "../../node_modules/.bin/eslint lib/ addons/" 14 | }, 15 | "dependencies": { 16 | "dispatchr": "^1.2.1", 17 | "is-promise": "^4.0.0", 18 | "setimmediate": "^1.0.5" 19 | }, 20 | "author": "Michael Ridgway ", 21 | "contributors": [], 22 | "licenses": [ 23 | { 24 | "type": "BSD-3-Clause", 25 | "url": "https://github.com/yahoo/fluxible/blob/master/LICENSE.md" 26 | } 27 | ], 28 | "homepage": "https://fluxible.io/", 29 | "keywords": [ 30 | "yahoo", 31 | "flux", 32 | "react", 33 | "fluxible", 34 | "isomorphic" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /packages/dispatchr/tests/mock/NoDehydrate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | var createStore = require('../../addons/createStore'); 6 | 7 | module.exports = createStore({ 8 | storeName: 'NoDehydrateStore', 9 | handlers: { 10 | NAVIGATE: 'navigate', 11 | }, 12 | initialize: function () { 13 | this.state = {}; 14 | this.called = false; 15 | this.defaultCalled = false; 16 | this.actionHandled = null; 17 | }, 18 | navigate: function (payload, actionName) { 19 | this.defaultCalled = true; 20 | this.actionHandled = actionName; 21 | this.emitChange(); 22 | }, 23 | shouldDehydrate: function () { 24 | return false; 25 | }, 26 | dehydrate: function () { 27 | throw new Error('Dehydrate should not be called on NoDehydrateStore'); 28 | }, 29 | rehydrate: function (state) { 30 | this.state = state; 31 | }, 32 | }); 33 | -------------------------------------------------------------------------------- /examples/chat/configs/routes.js: -------------------------------------------------------------------------------- 1 | var showChat = require('../actions/showChat'); 2 | var openThread = require('../actions/openThread'); 3 | 4 | module.exports = { 5 | home: { 6 | path: '/', 7 | method: 'get', 8 | action: function (context, payload, done) { 9 | context.executeAction(showChat, {}, done); 10 | }, 11 | }, 12 | thread: { 13 | path: '/thread/:id', 14 | method: 'get', 15 | action: function (context, payload, done) { 16 | var threadID = payload.params.id; 17 | context.executeAction( 18 | showChat, 19 | { threadID: threadID }, 20 | function () { 21 | context.executeAction( 22 | openThread, 23 | { threadID: threadID }, 24 | function () { 25 | done(); 26 | }, 27 | ); 28 | }, 29 | ); 30 | }, 31 | }, 32 | }; 33 | -------------------------------------------------------------------------------- /examples/doc-site/tests/unit/actions/doSearch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | /* global describe, it, beforeEach */ 6 | 'use strict'; 7 | import { expect } from 'chai'; 8 | import { createMockActionContext } from 'fluxible/utils'; 9 | import doSearch from '../../../actions/doSearch'; 10 | 11 | describe('site', () => { 12 | describe('do search', function () { 13 | let context; 14 | 15 | beforeEach(function () { 16 | context = createMockActionContext(); 17 | }); 18 | 19 | it('should execute the action', function (done) { 20 | doSearch(context, 'query', function () { 21 | expect(context.dispatchCalls.length).to.equal(1); 22 | expect(context.dispatchCalls[0].name).to.equal('DO_SEARCH'); 23 | expect(context.dispatchCalls[0].payload).to.equal('query'); 24 | done(); 25 | }); 26 | }); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /examples/fluxible-router/stores/ApplicationStore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import { BaseStore } from 'fluxible/addons'; 6 | 7 | class ApplicationStore extends BaseStore { 8 | constructor(dispatcher) { 9 | super(dispatcher); 10 | this.pageTitle = ''; 11 | } 12 | updatePageTitle(payload) { 13 | this.pageTitle = payload.pageTitle; 14 | this.emitChange(); 15 | } 16 | getPageTitle() { 17 | return this.pageTitle; 18 | } 19 | getState() { 20 | return { 21 | pageTitle: this.pageTitle, 22 | }; 23 | } 24 | dehydrate() { 25 | return this.getState(); 26 | } 27 | rehydrate(state) { 28 | this.pageTitle = state.pageTitle; 29 | } 30 | } 31 | 32 | ApplicationStore.storeName = 'ApplicationStore'; 33 | ApplicationStore.handlers = { 34 | UPDATE_PAGE_TITLE: 'updatePageTitle', 35 | }; 36 | 37 | export default ApplicationStore; 38 | -------------------------------------------------------------------------------- /examples/react-router/stores/TimeStore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | var createStore = require('fluxible/addons').createStore; 7 | 8 | var TimeStore = createStore({ 9 | storeName: 'TimeStore', 10 | initialize: function () { 11 | this.time = new Date(); 12 | }, 13 | handleTimeChange: function (payload) { 14 | this.time = new Date(); 15 | this.emitChange(); 16 | }, 17 | handlers: { 18 | CHANGE_ROUTE: 'handleTimeChange', 19 | UPDATE_TIME: 'handleTimeChange', 20 | }, 21 | getState: function () { 22 | return { 23 | time: this.time.toString(), 24 | }; 25 | }, 26 | dehydrate: function () { 27 | return { 28 | time: this.time.toString(), 29 | }; 30 | }, 31 | rehydrate: function (state) { 32 | this.time = new Date(state.time); 33 | }, 34 | }); 35 | 36 | module.exports = TimeStore; 37 | -------------------------------------------------------------------------------- /examples/doc-site/components/Status500.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 6 | import React from 'react'; 7 | import { NavLink } from 'fluxible-router'; 8 | 9 | class Status500 extends React.Component { 10 | render() { 11 | return ( 12 |
13 |
14 |
15 |

Error

16 |

Sorry there was an unexpected errror.

17 |

18 | 19 | Back to the home page. 20 | 21 |

22 |
23 |
24 |
25 | ); 26 | } 27 | } 28 | 29 | export default Status500; 30 | -------------------------------------------------------------------------------- /packages/generator-fluxible/app/templates/stores/ApplicationStore.js: -------------------------------------------------------------------------------- 1 | import BaseStore from 'fluxible/addons/BaseStore'; 2 | import RouteStore from './RouteStore'; 3 | 4 | class ApplicationStore extends BaseStore { 5 | constructor(dispatcher) { 6 | super(dispatcher); 7 | this.pageTitle = ''; 8 | } 9 | handlePageTitle(currentRoute) { 10 | this.dispatcher.waitFor(RouteStore, () => { 11 | if (currentRoute && currentRoute.title) { 12 | this.pageTitle = currentRoute.title; 13 | this.emitChange(); 14 | } 15 | }); 16 | } 17 | getPageTitle() { 18 | return this.pageTitle; 19 | } 20 | dehydrate() { 21 | return { 22 | pageTitle: this.pageTitle, 23 | }; 24 | } 25 | rehydrate(state) { 26 | this.pageTitle = state.pageTitle; 27 | } 28 | } 29 | 30 | ApplicationStore.storeName = 'ApplicationStore'; 31 | ApplicationStore.handlers = { 32 | NAVIGATE_SUCCESS: 'handlePageTitle', 33 | }; 34 | 35 | export default ApplicationStore; 36 | -------------------------------------------------------------------------------- /examples/doc-site/components/Status404.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 6 | import React from 'react'; 7 | import { NavLink } from 'fluxible-router'; 8 | 9 | class Status404 extends React.Component { 10 | render() { 11 | return ( 12 |
13 |
14 |
15 |

Not found

16 |

Sorry we could not find that resource.

17 |

18 | 19 | Back to the home page. 20 | 21 |

22 |
23 |
24 |
25 | ); 26 | } 27 | } 28 | 29 | export default Status404; 30 | -------------------------------------------------------------------------------- /examples/react-router/stores/ApplicationStore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | var createStore = require('fluxible/addons').createStore; 7 | 8 | var ApplicationStore = createStore({ 9 | storeName: 'ApplicationStore', 10 | handlers: { 11 | CHANGE_ROUTE: 'handleNavigate', 12 | }, 13 | initialize: function () { 14 | this.currentRoute = null; 15 | }, 16 | handleNavigate: function (route) { 17 | if (this.currentRoute && route.path === this.currentRoute.path) { 18 | return; 19 | } 20 | 21 | this.currentRoute = route; 22 | this.emitChange(); 23 | }, 24 | getState: function () { 25 | return { 26 | route: this.currentRoute, 27 | }; 28 | }, 29 | dehydrate: function () { 30 | return this.getState(); 31 | }, 32 | rehydrate: function (state) { 33 | this.currentRoute = state.route; 34 | }, 35 | }); 36 | 37 | module.exports = ApplicationStore; 38 | -------------------------------------------------------------------------------- /examples/minimal/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fluxible-minimal-example", 3 | "version": "1.0.0", 4 | "main": "dist/server.js", 5 | "author": "Pablo Palacios ", 6 | "private": true, 7 | "scripts": { 8 | "build": "NODE_ENV=production webpack", 9 | "dev": "npm run dev:browser & npm run dev:server", 10 | "dev:browser": "NODE_ENV=development webpack --watch --no-stats", 11 | "dev:server": "NODE_ENV=development nodemon", 12 | "start": "node ." 13 | }, 14 | "dependencies": { 15 | "express": "^4.17.1", 16 | "fluxible": "^1.4.0", 17 | "fluxible-addons-react": "^1.0.0", 18 | "fluxible-reducer-store": "^0.1.0", 19 | "react": "^17.0.2", 20 | "react-dom": "^17.0.2", 21 | "serialize-javascript": "^5.0.1" 22 | }, 23 | "devDependencies": { 24 | "@babel/core": "^7.13.16", 25 | "@babel/preset-env": "^7.13.15", 26 | "@babel/preset-react": "^7.13.13", 27 | "babel-loader": "^8.2.2", 28 | "nodemon": "^2.0.7", 29 | "webpack": "^5.36.1", 30 | "webpack-cli": "^4.6.0", 31 | "webpack-node-externals": "^3.0.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/create-react-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-react-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.11.4", 7 | "@testing-library/react": "^11.1.0", 8 | "@testing-library/user-event": "^12.1.10", 9 | "fluxible": "^1.4.0", 10 | "fluxible-addons-react": "^1.0.0", 11 | "fluxible-reducer-store": "^0.1.0", 12 | "react": "^17.0.2", 13 | "react-dom": "^17.0.2", 14 | "react-scripts": "4.0.3", 15 | "web-vitals": "^1.0.1" 16 | }, 17 | "scripts": { 18 | "start": "react-scripts start", 19 | "build": "react-scripts build", 20 | "test": "react-scripts test", 21 | "eject": "react-scripts eject" 22 | }, 23 | "eslintConfig": { 24 | "extends": [ 25 | "react-app", 26 | "react-app/jest" 27 | ] 28 | }, 29 | "browserslist": { 30 | "production": [ 31 | ">0.2%", 32 | "not dead", 33 | "not op_mini all" 34 | ], 35 | "development": [ 36 | "last 1 chrome version", 37 | "last 1 firefox version", 38 | "last 1 safari version" 39 | ] 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/fluxible/utils/MockComponentContext.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | 7 | var createMockActionContext = require('./createMockActionContext'); 8 | function noop() {} 9 | 10 | function MockComponentContext(dispatcherContext) { 11 | this.dispatcherContext = dispatcherContext; 12 | this.executeActionCalls = []; 13 | this.getStore = this.getStore.bind(this); 14 | this.executeAction = this.executeAction.bind(this); 15 | } 16 | 17 | MockComponentContext.prototype.getStore = function (name) { 18 | return this.dispatcherContext.getStore(name); 19 | }; 20 | 21 | MockComponentContext.prototype.executeAction = function (action, payload) { 22 | this.executeActionCalls.push({ 23 | action: action, 24 | payload: payload, 25 | }); 26 | action( 27 | createMockActionContext({ 28 | dispatcherContext: this.dispatcherContext, 29 | }), 30 | payload, 31 | noop, 32 | ); 33 | }; 34 | 35 | module.exports = MockComponentContext; 36 | -------------------------------------------------------------------------------- /examples/stale-props/src/ListStore.js: -------------------------------------------------------------------------------- 1 | import createStore from 'fluxible/addons/createStore'; 2 | 3 | const ListStore = createStore({ 4 | storeName: 'ListStore', 5 | 6 | initialize() { 7 | this.items = [ 8 | { 9 | id: 1, 10 | label: 'init', 11 | }, 12 | { 13 | id: 2, 14 | label: 'init2', 15 | }, 16 | { 17 | id: 3, 18 | label: 'init3', 19 | }, 20 | ]; 21 | }, 22 | 23 | handlers: { 24 | addItem: 'addItem', 25 | removeItem: 'removeItem', 26 | }, 27 | 28 | addItem(item) { 29 | this.items.push(item); 30 | this.emitChange(); 31 | }, 32 | 33 | removeItem({ itemId }) { 34 | this.items = this.items.filter(({ id }) => id !== itemId); 35 | this.emitChange(); 36 | }, 37 | 38 | getItems() { 39 | return this.items.map(({ id }) => id); 40 | }, 41 | 42 | getItem(itemId) { 43 | return this.items.find(({ id }) => id === itemId); 44 | }, 45 | }); 46 | 47 | export default ListStore; 48 | -------------------------------------------------------------------------------- /examples/chat/components/ChatApp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2014 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | const React = require('react'); 17 | const { provideContext } = require('fluxible-addons-react'); 18 | const { handleHistory } = require('fluxible-router'); 19 | const MessageSection = require('./MessageSection'); 20 | const ThreadSection = require('./ThreadSection'); 21 | 22 | const ChatApp = () => ( 23 |
24 | 25 | 26 |
27 | ); 28 | 29 | module.exports = provideContext(handleHistory(ChatApp)); 30 | -------------------------------------------------------------------------------- /docs/home.md: -------------------------------------------------------------------------------- 1 | # Features 2 | 3 | ## Singleton-free for server rendering 4 | 5 | [Stores](../packages/fluxible/docs/api/Stores.md) are classes that are instantiated per request or client session. This ensures that the stores are isolated and do not bleed information between requests. 6 | 7 | ## Dehydration/Rehydration 8 | 9 | [Stores](../packages/fluxible/docs/api/Stores.md) can provide `dehydrate` and `rehydrate` so that you can propagate the initial server state to the client. 10 | 11 | ## React Integration 12 | 13 | Helper utilities for integrating your Fluxible app into React [components](../packages/fluxible/docs/api/Components.md) with less boilerplate. 14 | 15 | ## Flow Regulation 16 | 17 | [FluxibleContext](../packages/fluxible/docs/api/FluxibleContext.md) restricts access to your Flux methods so that you can't break out of the unidirectional flow. 18 | 19 | ## Pluggable 20 | 21 | Want to add your own interfaces to the Flux flow? [Plugins](../packages/fluxible/docs/api/Plugins.md) allow you to add methods to any of the contexts. 22 | 23 | ## Updated for Latest React 24 | 25 | Updated to follow React's changes and the deprecations coming in the next version of React. 26 | -------------------------------------------------------------------------------- /packages/fluxible-addons-react/src/withFluxible.js: -------------------------------------------------------------------------------- 1 | import { createElement } from 'react'; 2 | import hoistNonReactStatics from 'hoist-non-react-statics'; 3 | import useFluxible from './useFluxible'; 4 | 5 | /** 6 | * Higher-order component that injects the fluxible context as context 7 | * prop. 8 | * 9 | * const MyComponent = ({ context }) => { 10 | * const onClick = () => context.executeAction(myAction); 11 | * return 22 | 23 | ); 24 | }; 25 | 26 | export default connectToStores( 27 | Item, 28 | [ListStore], 29 | ({ getStore, executeAction }, { itemId }) => ({ 30 | item: getStore(ListStore).getItem(itemId), 31 | remove: () => executeAction(removeItem, { itemId }), 32 | }), 33 | ); 34 | -------------------------------------------------------------------------------- /examples/chat/actions/showChat.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | var debug = require('debug')('Example:showChatAction'); 7 | var MessageStore = require('../stores/MessageStore'); 8 | var openThread = require('../actions/openThread'); 9 | 10 | function fetchMessages(context, payload, done) { 11 | debug('fetching messages'); 12 | context.service.read('message', {}, {}, function (err, messages) { 13 | context.dispatch('RECEIVE_MESSAGES', messages); 14 | context.executeAction(openThread, payload, function () { 15 | context.dispatch('SHOW_CHAT_END'); 16 | done(); 17 | }); 18 | }); 19 | } 20 | 21 | module.exports = function (context, payload, done) { 22 | context.dispatch('SHOW_CHAT_START'); 23 | var messageStore = context.getStore(MessageStore); 24 | 25 | if (Object.keys(messageStore.getAll()).length === 0) { 26 | fetchMessages(context, payload, done); 27 | } else { 28 | debug('dispatching SHOW_CHAT_END'); 29 | context.dispatch('SHOW_CHAT_END'); 30 | done(); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /examples/doc-site/tests/unit/actions/showSearch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | /* global describe, it, beforeEach */ 6 | 'use strict'; 7 | import { expect } from 'chai'; 8 | import { createMockActionContext } from 'fluxible/utils'; 9 | import showSearch from '../../../actions/showSearch'; 10 | 11 | describe('site', () => { 12 | describe('show search', function () { 13 | let context; 14 | 15 | beforeEach(function () { 16 | context = createMockActionContext(); 17 | }); 18 | 19 | it('should execute the action', function (done) { 20 | const route = { 21 | query: { 22 | q: 'foo', 23 | }, 24 | }; 25 | 26 | showSearch(context, route, function () { 27 | expect(context.dispatchCalls.length).to.equal(1); 28 | expect(context.dispatchCalls[0].name).to.equal('DO_SEARCH'); 29 | expect(context.dispatchCalls[0].payload).to.equal('foo'); 30 | done(); 31 | }); 32 | }); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /packages/dispatchr/tests/mock/DelayedStore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | var createStore = require('../../addons/createStore'); 6 | 7 | module.exports = createStore({ 8 | storeName: 'DelayedStore', 9 | handlers: { 10 | DELAY: 'delay', 11 | default: 'default', 12 | }, 13 | initialize: function () { 14 | this.state = {}; 15 | this.called = false; 16 | this.defaultCalled = false; 17 | this.actionHandled = null; 18 | }, 19 | default: function (payload, actionName) { 20 | this.defaultCalled = true; 21 | this.actionHandled = actionName; 22 | this.emitChange(); 23 | }, 24 | delay: function (payload) { 25 | this.called = true; 26 | this.state.page = 'delay'; 27 | this.state.final = true; 28 | this.emitChange(); 29 | }, 30 | getState: function () { 31 | return this.state; 32 | }, 33 | dehydrate: function () { 34 | return this.state; 35 | }, 36 | rehydrate: function (state) { 37 | this.state = state; 38 | }, 39 | }); 40 | -------------------------------------------------------------------------------- /packages/fluxible/tests/fixtures/plugins/DimensionsContextPluginSync.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | 7 | module.exports = function (dims) { 8 | var dimensions = dims; 9 | return { 10 | name: 'DimensionsPlugin', 11 | plugActionContext: function (actionContext) { 12 | actionContext.getDimensions = function () { 13 | return dimensions; 14 | }; 15 | }, 16 | plugComponentContext: function (componentContext) { 17 | componentContext.getDimensions = function () { 18 | return dimensions; 19 | }; 20 | }, 21 | plugStoreContext: function (storeContext) { 22 | storeContext.getDimensions = function () { 23 | return dimensions; 24 | }; 25 | }, 26 | dehydrate: function () { 27 | return { 28 | dimensions: dimensions, 29 | }; 30 | }, 31 | rehydrate: function (state) { 32 | dimensions = state.dimensions; 33 | }, 34 | }; 35 | }; 36 | -------------------------------------------------------------------------------- /packages/fluxible-router/tests/mocks/MockAppComponent.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 6 | const React = require('react'); 7 | const PropTypes = require('prop-types'); 8 | const { provideContext } = require('fluxible-addons-react'); 9 | const { handleHistory } = require('../../'); 10 | 11 | class MockAppComponent extends React.Component { 12 | render() { 13 | if (!this.props.children) { 14 | return null; 15 | } 16 | return React.cloneElement(this.props.children, { 17 | currentRoute: this.props.currentRoute, 18 | }); 19 | } 20 | } 21 | 22 | MockAppComponent.propTypes = { 23 | children: PropTypes.object, 24 | currentRoute: PropTypes.object, 25 | }; 26 | 27 | module.exports.default = provideContext( 28 | handleHistory(MockAppComponent, { 29 | checkRouteOnPageLoad: false, 30 | enableScroll: true, 31 | }), 32 | ); 33 | 34 | module.exports.createWrappedMockAppComponent = 35 | function createWrappedMockAppComponent(opts) { 36 | return provideContext(handleHistory(MockAppComponent, opts)); 37 | }; 38 | -------------------------------------------------------------------------------- /examples/doc-site/plugins/queryPlugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Adds query params information to context 5 | * @returns {Object} queryPlugin 6 | * @module queryPlugin 7 | */ 8 | export default function queryPlugin() { 9 | return { 10 | name: 'QueryPlugin', 11 | plugContext: function (contextOptions) { 12 | var req = contextOptions.req; 13 | var query = req && req.query; 14 | 15 | return { 16 | plugActionContext: function (actionContext) { 17 | actionContext.query = query; 18 | }, 19 | plugComponentContext: function (componentContext) { 20 | componentContext.query = query; 21 | }, 22 | plugStoreContext: function (storeContext) { 23 | storeContext.query = query; 24 | }, 25 | dehydrate: function () { 26 | return { 27 | query: query, 28 | }; 29 | }, 30 | rehydrate: function (state) { 31 | query = state.query; 32 | }, 33 | }; 34 | }, 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /examples/fluxible-router/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fluxible-router-example", 3 | "private": true, 4 | "version": "0.0.0", 5 | "description": "Example application", 6 | "main": "server.js", 7 | "author": "Michael Ridgway ", 8 | "scripts": { 9 | "dev": "webpack serve & PORT=3001 nodemon start.js -e js,jsx", 10 | "start": "node start.js", 11 | "dev-browser": "cd browser-only && webpack serve" 12 | }, 13 | "dependencies": { 14 | "@babel/register": "^7.13.16", 15 | "fluxible": "^1.4.0", 16 | "fluxible-addons-react": "^1.0.0", 17 | "fluxible-router": "^2.0.0", 18 | "prop-types": "^15.7.2", 19 | "react": "^17.0.2", 20 | "react-dom": "^17.0.2", 21 | "react-helmet": "^6.1.0" 22 | }, 23 | "devDependencies": { 24 | "@babel/core": "^7.14.0", 25 | "@babel/preset-env": "^7.14.0", 26 | "@babel/preset-react": "^7.13.13", 27 | "babel-loader": "^8.2.2", 28 | "html-webpack-plugin": "^5.3.1", 29 | "nodemon": "^2.0.7", 30 | "webpack": "^5.36.2", 31 | "webpack-cli": "^4.6.0", 32 | "webpack-dev-server": "^3.11.2" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/fluxible-addons-react/tests/unit/lib/useFluxible.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react'); 2 | const TestRenderer = require('react-test-renderer'); 3 | const createMockComponentContext = require('fluxible/utils/createMockComponentContext'); 4 | const FooStore = require('../../fixtures/stores/FooStore'); 5 | const { useFluxible, FluxibleProvider } = require('../../../'); 6 | 7 | describe('fluxible-addons-react', () => { 8 | describe('useFluxible', () => { 9 | it('returns fluxible context', () => { 10 | const FooComponent = () => { 11 | const context = useFluxible(); 12 | const foo = context.getStore(FooStore).getFoo(); 13 | return

; 14 | }; 15 | 16 | const context = createMockComponentContext({ stores: [FooStore] }); 17 | 18 | const testRenderer = TestRenderer.create( 19 | 20 | 21 | , 22 | ); 23 | 24 | const component = testRenderer.root.findByType('p'); 25 | 26 | expect(component.props.id).toEqual('bar'); 27 | }); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /packages/generator-fluxible/app/templates/components/Html.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import ApplicationStore from '../stores/ApplicationStore'; 4 | 5 | const Html = ({ context, markup, state, clientFile }) => ( 6 | 7 | 8 | 9 | {context.getStore(ApplicationStore).getPageTitle()} 10 | 14 | 18 | 19 | 20 |

21 | 22 | 23 | 24 | 25 | ); 26 | 27 | Html.propTypes = { 28 | clientFile: PropTypes.string, 29 | context: PropTypes.object, 30 | markup: PropTypes.string, 31 | state: PropTypes.string, 32 | }; 33 | 34 | export default Html; 35 | -------------------------------------------------------------------------------- /packages/generator-fluxible/app/templates/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const nodeExternals = require('webpack-node-externals'); 3 | 4 | const isProduction = process.env.NODE_ENV !== 'development'; 5 | 6 | const commonConfig = { 7 | mode: isProduction ? 'production' : 'development', 8 | module: { 9 | rules: [ 10 | { 11 | test: /\.m?js$/, 12 | exclude: /node_modules/, 13 | use: { loader: 'babel-loader' }, 14 | }, 15 | ], 16 | }, 17 | }; 18 | 19 | const browserConfig = { 20 | ...commonConfig, 21 | target: 'web', 22 | entry: './client.js', 23 | output: { 24 | filename: isProduction ? 'main.min.js' : 'main.js', 25 | path: path.resolve('./dist/public'), 26 | publicPath: '/public/', 27 | }, 28 | }; 29 | 30 | const serverConfig = { 31 | ...commonConfig, 32 | target: 'node', 33 | entry: './server.js', 34 | output: { 35 | filename: 'server.js', 36 | path: path.resolve(__dirname, 'dist'), 37 | }, 38 | externals: [nodeExternals()], 39 | externalsPresets: { node: true }, 40 | }; 41 | 42 | module.exports = [browserConfig, serverConfig]; 43 | -------------------------------------------------------------------------------- /examples/fluxible-router/components/Application.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import React from 'react'; 6 | import { Helmet } from 'react-helmet'; 7 | import { connectToStores, provideContext } from 'fluxible-addons-react'; 8 | import { handleHistory } from 'fluxible-router'; 9 | import Nav from './Nav'; 10 | import Timestamp from './Timestamp'; 11 | import ApplicationStore from '../stores/ApplicationStore'; 12 | 13 | const Application = ({ currentRoute, pageTitle }) => { 14 | const Handler = currentRoute.handler; 15 | 16 | return ( 17 | <> 18 | 19 | {pageTitle} 20 | 21 |
22 |
26 | 27 | ); 28 | }; 29 | 30 | export default provideContext( 31 | handleHistory( 32 | connectToStores(Application, [ApplicationStore], (context) => ({ 33 | ...context.getStore(ApplicationStore).getState(), 34 | })), 35 | { enableScroll: false }, 36 | ), 37 | ); 38 | -------------------------------------------------------------------------------- /packages/fluxible/utils/MockActionContext.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | var callAction = require('./callAction'); 7 | var generateUUID = require('./generateUUID'); 8 | 9 | function MockActionContext(dispatcherContext) { 10 | this.dispatcherContext = dispatcherContext; 11 | this.executeActionCalls = []; 12 | this.dispatchCalls = []; 13 | this.rootId = generateUUID(); 14 | } 15 | 16 | MockActionContext.prototype.getStore = function (name) { 17 | return this.dispatcherContext.getStore(name); 18 | }; 19 | 20 | MockActionContext.prototype.dispatch = function (name, payload) { 21 | this.dispatchCalls.push({ 22 | name: name, 23 | payload: payload, 24 | }); 25 | this.dispatcherContext.dispatch(name, payload); 26 | }; 27 | 28 | MockActionContext.prototype.executeAction = function ( 29 | action, 30 | payload, 31 | callback, 32 | ) { 33 | this.executeActionCalls.push({ 34 | action: action, 35 | payload: payload, 36 | }); 37 | return callAction(this, action, payload, callback); 38 | }; 39 | 40 | module.exports = MockActionContext; 41 | -------------------------------------------------------------------------------- /examples/chat/actions/createMessage.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | var debug = require('debug')('Example:createMessageAction'); 7 | var ThreadStore = require('../stores/ThreadStore'); 8 | 9 | module.exports = function (context, payload, done) { 10 | var threadStore = context.getStore(ThreadStore); 11 | var message = threadStore.createMessage({ 12 | timestamp: Date.now(), 13 | authorName: 'Bill', // hard coded for the example 14 | isRead: true, 15 | text: payload.text, 16 | }); 17 | debug('dispatching RECEIVE_MESSAGES', message); 18 | context.dispatch('RECEIVE_MESSAGES', [message]); 19 | context.service.create('message', message, {}, function (err) { 20 | if (err) { 21 | debug('dispatching RECEIVE_MESSAGES_FAILURE', message); 22 | context.dispatch('RECEIVE_MESSAGES_FAILURE', [message]); 23 | done(); 24 | return; 25 | } 26 | debug('dispatching RECEIVE_MESSAGES_SUCCESS', message); 27 | context.dispatch('RECEIVE_MESSAGES_SUCCESS', [message]); 28 | done(); 29 | }); 30 | }; 31 | -------------------------------------------------------------------------------- /examples/stale-props/README.md: -------------------------------------------------------------------------------- 1 | # Stale props example 2 | 3 | This example shows how to handle the stale props issue. The stale 4 | props issue happens when the following conditions are met: 5 | 6 | 1. A child component relies on its props to retrieve data from the store 7 | 2. The child component subscribes to the store before its parent. 8 | 9 | A concrete example would be a TODO app with the follow features: 10 | 11 | 1. It populates the store in the client with data from the server 12 | through the rehydration (SSR). 13 | 2. The parent component would be a list that retrieves only the items 14 | ids from the store and renders each item by passing only their ids 15 | as props. 16 | 3. The child component would be each item that takes the id from the 17 | props and retrieves the remaining data from the store by 18 | subscribing to it. 19 | 20 | In the above scenario, after deleting one item that came from the 21 | rehydration process, the app could crash if the item component is not 22 | handling the case where the item content doesn't exist anymore in the 23 | store. 24 | 25 | This examples shows a possibility on how to handle the above case. 26 | 27 | ## How to run it 28 | 29 | ```bash 30 | npm install 31 | npm start 32 | ``` 33 | -------------------------------------------------------------------------------- /packages/fluxible/tests/fixtures/plugins/DimensionsContextPlugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | 7 | module.exports = function (dims) { 8 | var dimensions = dims; 9 | return { 10 | name: 'DimensionsPlugin', 11 | plugActionContext: function (actionContext) { 12 | actionContext.getDimensions = function () { 13 | return dimensions; 14 | }; 15 | }, 16 | plugComponentContext: function (componentContext) { 17 | componentContext.getDimensions = function () { 18 | return dimensions; 19 | }; 20 | }, 21 | plugStoreContext: function (storeContext) { 22 | storeContext.getDimensions = function () { 23 | return dimensions; 24 | }; 25 | }, 26 | dehydrate: function () { 27 | return { 28 | dimensions: dimensions, 29 | }; 30 | }, 31 | rehydrate: function (state, done) { 32 | dimensions = state.dimensions; 33 | setImmediate(done); 34 | }, 35 | }; 36 | }; 37 | -------------------------------------------------------------------------------- /examples/fluxible-router/components/Html.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import React from 'react'; 6 | import PropTypes from 'prop-types'; 7 | 8 | const HtmlComponent = ({ helmet, markup, state }) => ( 9 | 10 | 11 | 12 | {helmet.title.toComponent()} 13 | 17 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | ); 29 | 30 | HtmlComponent.propTypes = { 31 | helmet: PropTypes.object.isRequired, 32 | markup: PropTypes.string.isRequired, 33 | state: PropTypes.string.isRequired, 34 | }; 35 | 36 | export default HtmlComponent; 37 | -------------------------------------------------------------------------------- /examples/chat/components/MessageListItem.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2014 Facebook, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | const React = require('react'); 17 | const PropTypes = require('prop-types'); 18 | 19 | const MessageListItem = ({ message }) => ( 20 |
  • 21 |
    {message.authorName}
    22 |
    23 | {new Date(message.timestamp).toTimeString()} 24 |
    25 |
    {message.text}
    26 |
  • 27 | ); 28 | 29 | MessageListItem.propTypes = { 30 | message: PropTypes.object, 31 | }; 32 | 33 | module.exports = MessageListItem; 34 | -------------------------------------------------------------------------------- /packages/generator-fluxible/app/templates/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= name %>", 3 | "version": "0.0.0", 4 | "private": true, 5 | "main": "dist/server.js", 6 | "scripts": { 7 | "build": "NODE_ENV=production webpack", 8 | "dev": "npm run dev:browser & npm run dev:server", 9 | "dev:browser": "NODE_ENV=development webpack --watch --no-stats", 10 | "dev:server": "NODE_ENV=development nodemon", 11 | "start": "node ." 12 | }, 13 | "dependencies": { 14 | "body-parser": "^1.19.0", 15 | "compression": "^1.7.4", 16 | "express": "^4.17.1", 17 | "fluxible": "^1.0.0", 18 | "fluxible-addons-react": "^1.0.0", 19 | "fluxible-plugin-fetchr": "^0.4.0", 20 | "fluxible-router": "^2.0.0", 21 | "react": "^17.0.2", 22 | "react-dom": "^17.0.2", 23 | "serialize-javascript": "^5.0.1" 24 | }, 25 | "devDependencies": { 26 | "@babel/core": "^7.13.16", 27 | "@babel/preset-env": "^7.13.15", 28 | "@babel/preset-react": "^7.13.13", 29 | "babel-loader": "^8.2.2", 30 | "nodemon": "^2.0.7", 31 | "webpack": "^5.36.1", 32 | "webpack-cli": "^4.6.0", 33 | "webpack-node-externals": "^3.0.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /examples/chat/components/Html.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | const React = require('react'); 6 | const PropTypes = require('prop-types'); 7 | 8 | /** 9 | * Stateless React component to handle the rendering of the HTML head section 10 | */ 11 | const Html = (props) => ( 12 | 13 | 14 | 15 | {props.title} 16 | 20 | 21 | 22 | 23 |
    27 | 28 | 29 | 30 | 31 | ); 32 | 33 | Html.propTypes = { 34 | title: PropTypes.object, 35 | markup: PropTypes.string.isRequired, 36 | state: PropTypes.string.isRequired, 37 | }; 38 | 39 | module.exports = Html; 40 | -------------------------------------------------------------------------------- /packages/fluxible-plugin-devtools/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fluxible-plugin-devtools", 3 | "version": "0.1.9", 4 | "description": "A plugin for Fluxible applications to provide debugging information", 5 | "main": "index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git://github.com/yahoo/fluxible.git" 9 | }, 10 | "scripts": { 11 | "pretest": "npm run dist", 12 | "test": "../../node_modules/.bin/jest", 13 | "precover": "npm run dist", 14 | "cover": "../../node_modules/.bin/jest --coverage", 15 | "lint": "../../node_modules/.bin/eslint src/ index.js", 16 | "dist": "../../node_modules/.bin/babel --root-mode upward src -d dist", 17 | "prepublish": "npm run dist" 18 | }, 19 | "dependencies": { 20 | "prop-types": "^15.7.2" 21 | }, 22 | "peerDependencies": { 23 | "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" 24 | }, 25 | "author": "Rajiv Tirumalareddy ", 26 | "contributors": [], 27 | "licenses": [ 28 | { 29 | "type": "BSD-3-Clause", 30 | "url": "https://github.com/yahoo/fluxible/blob/master/LICENSE.md" 31 | } 32 | ], 33 | "keywords": [ 34 | "yahoo", 35 | "flux", 36 | "react", 37 | "fluxible", 38 | "performance", 39 | "devtools" 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /examples/todo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flux-example-todo", 3 | "private": true, 4 | "version": "0.0.0", 5 | "description": "Example application", 6 | "main": "start.js", 7 | "author": "Reza Akhavan ", 8 | "scripts": { 9 | "dev": "webpack serve & PORT=3001 nodemon start.js -e js,jsx", 10 | "start": "node start.js" 11 | }, 12 | "dependencies": { 13 | "@babel/register": "^7.13.16", 14 | "classnames": "^2.3.1", 15 | "cookie-parser": "^1.4.5", 16 | "csurf": "^1.11.0", 17 | "fluxible": "^1.4.0", 18 | "fluxible-addons-react": "^1.0.0", 19 | "fluxible-plugin-fetchr": "^0.4.0", 20 | "fluxible-router": "^2.0.0", 21 | "prop-types": "^15.7.2", 22 | "react": "^17.0.2", 23 | "react-dom": "^17.0.2", 24 | "react-helmet": "^6.1.0" 25 | }, 26 | "devDependencies": { 27 | "@babel/core": "^7.14.0", 28 | "@babel/preset-env": "^7.14.0", 29 | "@babel/preset-react": "^7.13.13", 30 | "babel-loader": "^8.2.2", 31 | "html-webpack-plugin": "^5.3.1", 32 | "nodemon": "^2.0.7", 33 | "webpack": "^5.36.2", 34 | "webpack-cli": "^4.6.0", 35 | "webpack-dev-server": "^3.11.2" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /examples/chat/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flux-example-chat", 3 | "private": true, 4 | "version": "0.0.0", 5 | "description": "Example application", 6 | "main": "start.js", 7 | "author": "Michael Ridgway ", 8 | "scripts": { 9 | "dev": "webpack serve & PORT=3001 nodemon start.js -e js,jsx", 10 | "start": "node start.js" 11 | }, 12 | "dependencies": { 13 | "@babel/register": "^7.13.16", 14 | "classnames": "^2.3.1", 15 | "cookie-parser": "^1.4.5", 16 | "csurf": "^1.11.0", 17 | "fluxible": "^1.4.0", 18 | "fluxible-addons-react": "^1.0.0", 19 | "fluxible-plugin-fetchr": "^0.4.0", 20 | "fluxible-router": "^2.0.0", 21 | "prop-types": "^15.7.2", 22 | "react": "^17.0.2", 23 | "react-dom": "^17.0.2", 24 | "react-helmet": "^6.1.0" 25 | }, 26 | "devDependencies": { 27 | "@babel/core": "^7.14.0", 28 | "@babel/preset-env": "^7.14.0", 29 | "@babel/preset-react": "^7.13.13", 30 | "babel-loader": "^8.2.2", 31 | "html-webpack-plugin": "^5.3.1", 32 | "nodemon": "^2.0.7", 33 | "webpack": "^5.36.2", 34 | "webpack-cli": "^4.6.0", 35 | "webpack-dev-server": "^3.11.2" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /examples/chat/stores/UnreadThreadStore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | var createStore = require('fluxible/addons').createStore; 7 | var ThreadStore = require('./ThreadStore'); 8 | 9 | var UnreadThreadStore = createStore({ 10 | storeName: 'UnreadThreadStore', 11 | handlers: { 12 | RECEIVE_MESSAGES: 'receiveMessages', 13 | OPEN_THREAD: 'openThread', 14 | }, 15 | initialize: function () { 16 | this.messages = {}; 17 | }, 18 | receiveMessages: function (messages) { 19 | this.emitChange(); 20 | }, 21 | openThread: function (payload) { 22 | this.emitChange(); 23 | }, 24 | getCount: function () { 25 | var threads = this.dispatcher.getStore(ThreadStore).getAll(); 26 | var unreadCount = 0; 27 | for (var id in threads) { 28 | if (!threads[id].lastMessage.isRead) { 29 | unreadCount++; 30 | } 31 | } 32 | return unreadCount; 33 | }, 34 | dehydrate: function () { 35 | return {}; 36 | }, 37 | rehydrate: function (state) { 38 | return; 39 | }, 40 | }); 41 | 42 | module.exports = UnreadThreadStore; 43 | -------------------------------------------------------------------------------- /packages/fluxible-addons-react/src/createElementWithContext.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import { Component, createElement } from 'react'; 6 | import FluxibleComponent from './FluxibleComponent'; 7 | 8 | /** 9 | * Creates an instance of the app level component with given props and a proper component 10 | * context. 11 | * @param {FluxibleContext} fluxibleContext 12 | * @param {Object} props 13 | * @return {ReactElement} 14 | */ 15 | function createElementWithContext(fluxibleContext, props) { 16 | const Component = fluxibleContext.getComponent(); 17 | if (!Component) { 18 | throw new Error( 19 | 'A top-level component was not passed to the Fluxible constructor.', 20 | ); 21 | } 22 | 23 | const context = fluxibleContext.getComponentContext(); 24 | 25 | if ( 26 | Component.displayName && 27 | Component.displayName.includes('contextProvider') 28 | ) { 29 | return createElement(Component, { context, ...props }); 30 | } 31 | 32 | const children = createElement(Component, props); 33 | return createElement(FluxibleComponent, { context }, children); 34 | } 35 | 36 | export default createElementWithContext; 37 | -------------------------------------------------------------------------------- /packages/fluxible-addons-react/src/provideContext.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import { createElement } from 'react'; 6 | import { object } from 'prop-types'; 7 | import hoistNonReactStatics from 'hoist-non-react-statics'; 8 | import FluxibleProvider from './FluxibleProvider'; 9 | 10 | /** 11 | * Provides context prop to all children as React context 12 | * 13 | * Example: 14 | * const WrappedComponent = provideContext(Component); 15 | * 16 | * @function provideContext 17 | * @param {React.Component} Component - component to wrap. 18 | * @returns {React.Component} 19 | */ 20 | function provideContext(Component) { 21 | const ContextProvider = (props) => 22 | createElement( 23 | FluxibleProvider, 24 | { context: props.context }, 25 | createElement(Component, props), 26 | ); 27 | 28 | ContextProvider.propTypes = { 29 | context: object.isRequired, 30 | }; 31 | 32 | ContextProvider.displayName = `contextProvider(${ 33 | Component.displayName || Component.name || 'Component' 34 | })`; 35 | 36 | return hoistNonReactStatics(ContextProvider, Component); 37 | } 38 | 39 | export default provideContext; 40 | -------------------------------------------------------------------------------- /packages/fluxible-addons-react/tests/unit/lib/withFluxible.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/prop-types */ 2 | const React = require('react'); 3 | const TestRenderer = require('react-test-renderer'); 4 | const createMockComponentContext = require('fluxible/utils/createMockComponentContext'); 5 | const FooStore = require('../../fixtures/stores/FooStore'); 6 | const { withFluxible, FluxibleProvider } = require('../../../'); 7 | 8 | describe('fluxible-addons-react', () => { 9 | describe('withFluxible', () => { 10 | it('forwards fluxible context to wrapped component', () => { 11 | let FooComponent = ({ context }) => { 12 | const foo = context.getStore(FooStore).getFoo(); 13 | return

    ; 14 | }; 15 | 16 | FooComponent = withFluxible(FooComponent); 17 | 18 | const context = createMockComponentContext({ stores: [FooStore] }); 19 | 20 | const testRenderer = TestRenderer.create( 21 | 22 | 23 | , 24 | ); 25 | 26 | const component = testRenderer.root.findByType('p'); 27 | 28 | expect(component.props.id).toEqual('bar'); 29 | }); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /packages/fluxible/tests/fixtures/plugins/DimensionsContextPluginPromise.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | 7 | module.exports = function (dims) { 8 | var dimensions = dims; 9 | return { 10 | name: 'DimensionsPlugin', 11 | plugActionContext: function (actionContext) { 12 | actionContext.getDimensions = function () { 13 | return dimensions; 14 | }; 15 | }, 16 | plugComponentContext: function (componentContext) { 17 | componentContext.getDimensions = function () { 18 | return dimensions; 19 | }; 20 | }, 21 | plugStoreContext: function (storeContext) { 22 | storeContext.getDimensions = function () { 23 | return dimensions; 24 | }; 25 | }, 26 | dehydrate: function () { 27 | return { 28 | dimensions: dimensions, 29 | }; 30 | }, 31 | rehydrate: function (state) { 32 | return new Promise(function (resolve) { 33 | dimensions = state.dimensions; 34 | resolve(); 35 | }); 36 | }, 37 | }; 38 | }; 39 | -------------------------------------------------------------------------------- /examples/react-router/components/Nav.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import React from 'react'; 6 | import { Link } from 'react-router'; 7 | import PropTypes from 'prop-types'; 8 | 9 | class Nav extends React.Component { 10 | static contextTypes = { 11 | router: PropTypes.object.isRequired, 12 | }; 13 | 14 | render() { 15 | return ( 16 |

      17 |
    • 24 | Home 25 |
    • 26 |
    • 33 | About 34 |
    • 35 |
    36 | ); 37 | } 38 | } 39 | 40 | export default Nav; 41 | -------------------------------------------------------------------------------- /examples/react-router/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flux-example-routing", 3 | "private": true, 4 | "version": "0.0.0", 5 | "description": "Example application", 6 | "main": "start.js", 7 | "author": "Michael Ridgway ", 8 | "scripts": { 9 | "dev": "webpack serve & PORT=3001 nodemon start.js -e js,jsx", 10 | "start": "node start.js" 11 | }, 12 | "dependencies": { 13 | "@babel/register": "^7.13.16", 14 | "classnames": "^2.3.1", 15 | "cookie-parser": "^1.4.5", 16 | "csurf": "^1.11.0", 17 | "fluxible": "^1.4.0", 18 | "fluxible-addons-react": "^1.0.0", 19 | "fluxible-plugin-fetchr": "^0.4.0", 20 | "fluxible-router": "^2.0.0", 21 | "prop-types": "^15.7.2", 22 | "react": "^16.14.0", 23 | "react-dom": "^16.14.0", 24 | "react-helmet": "^6.1.0", 25 | "react-router": "^3.2.6" 26 | }, 27 | "devDependencies": { 28 | "@babel/core": "^7.14.0", 29 | "@babel/preset-env": "^7.14.0", 30 | "@babel/preset-react": "^7.13.13", 31 | "babel-loader": "^8.2.2", 32 | "html-webpack-plugin": "^5.3.1", 33 | "nodemon": "^2.0.7", 34 | "webpack": "^5.36.2", 35 | "webpack-cli": "^4.6.0", 36 | "webpack-dev-server": "^3.11.2" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/fluxible-addons-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fluxible-addons-react", 3 | "version": "1.2.0", 4 | "description": "Fluxible addons for use with React", 5 | "main": "dist/lib/index.js", 6 | "module": "dist/es/index.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/yahoo/fluxible" 10 | }, 11 | "scripts": { 12 | "dist": "rm -rf dist && npm run dist:commonjs && npm run dist:es", 13 | "dist:commonjs": "../../node_modules/.bin/babel --root-mode upward --env-name commonjs src -d dist/lib", 14 | "dist:es": "../../node_modules/.bin/babel --root-mode upward --env-name es src -d dist/es", 15 | "precover": "npm run dist", 16 | "prepublish": "npm run dist", 17 | "pretest": "npm run dist", 18 | "test": "../../node_modules/.bin/jest -c ../../jest.config.js", 19 | "cover": "../../node_modules/.bin/jest -c ../../jest.config.js --coverage", 20 | "lint": "../../node_modules/.bin/eslint src/*.js tests/" 21 | }, 22 | "dependencies": { 23 | "@babel/runtime": "^7.14.0", 24 | "hoist-non-react-statics": "^3.3.2", 25 | "prop-types": "^15.7.2" 26 | }, 27 | "peerDependencies": { 28 | "fluxible": ">=1.0.0", 29 | "react": "^16.3.0 || ^17.0.0", 30 | "react-dom": "^16.3.0 || ^17.0.0" 31 | }, 32 | "author": "Michael Ridgway ", 33 | "license": "BSD-3-Clause" 34 | } 35 | -------------------------------------------------------------------------------- /packages/generator-fluxible/app/templates/components/Nav.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { NavLink } from 'fluxible-router'; 4 | 5 | class Nav extends React.Component { 6 | render() { 7 | const selected = this.props.currentRoute; 8 | const links = this.props.links; 9 | 10 | const linkHTML = Object.keys(links).map((name) => { 11 | var className = ''; 12 | var link = links[name]; 13 | 14 | if (selected && selected.name === name) { 15 | className = 'pure-menu-selected'; 16 | } 17 | 18 | return ( 19 |
  • 20 | 24 | {link.title} 25 | 26 |
  • 27 | ); 28 | }); 29 | 30 | return ( 31 |
      32 | {linkHTML} 33 |
    34 | ); 35 | } 36 | } 37 | 38 | Nav.defaultProps = { 39 | selected: null, 40 | links: {}, 41 | }; 42 | 43 | Nav.propTypes = { 44 | currentRoute: PropTypes.object, 45 | links: PropTypes.object, 46 | }; 47 | 48 | export default Nav; 49 | -------------------------------------------------------------------------------- /examples/react-router/components/Html.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | import React from 'react'; 6 | import ApplicationStore from '../stores/ApplicationStore'; 7 | 8 | class HtmlComponent extends React.Component { 9 | render() { 10 | return ( 11 | 12 | 13 | 14 | React Router Example 15 | 19 | 23 | 24 | 25 |
    29 | 32 | 33 | 34 | 35 | ); 36 | } 37 | } 38 | 39 | export default HtmlComponent; 40 | -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | types: [opened, synchronize] 8 | 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@v3 15 | - name: Setup node 16 | uses: actions/setup-node@v2 17 | with: 18 | node-version: 18 19 | - name: Install dependencies 20 | run: npm install 21 | - name: Build code 22 | run: npm run build 23 | - name: Format code 24 | run: npm run format:check 25 | - name: Test code 26 | run: npm test 27 | publish: 28 | runs-on: ubuntu-latest 29 | needs: [test] 30 | if: "${{ github.repository_owner == 'yahoo' && github.event_name == 'push' }}" 31 | steps: 32 | - name: Checkout code 33 | uses: actions/checkout@v3 34 | - name: Setup node 35 | uses: actions/setup-node@v3 36 | with: 37 | node-version: 18 38 | - name: Install dependencies 39 | run: npm install 40 | - name: Build code 41 | run: npm run build 42 | - name: Publish to npm 43 | id: changesets 44 | uses: changesets/action@v1 45 | with: 46 | version: npm run version 47 | publish: npm run publish 48 | commit: '[ci] publish' 49 | title: '[ci] publish' 50 | env: 51 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 52 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 53 | -------------------------------------------------------------------------------- /examples/minimal/src/server.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import ReactDOMServer from 'react-dom/server'; 3 | import express from 'express'; 4 | import { createElementWithContext } from 'fluxible-addons-react'; 5 | import serialize from 'serialize-javascript'; 6 | import fluxibleApp from './fluxibleApp'; 7 | import * as actions from './actions'; 8 | 9 | const app = express(); 10 | 11 | app.use('/assets', express.static(path.join(__dirname, 'assets'))); 12 | 13 | app.get('*', (req, res) => { 14 | const context = fluxibleApp.createContext(); 15 | 16 | context 17 | .executeAction(actions.setRandomNumber) 18 | .then(() => { 19 | const element = createElementWithContext(context); 20 | const markup = ReactDOMServer.renderToString(element); 21 | const state = serialize(fluxibleApp.dehydrate(context)); 22 | 23 | res.send(` 24 | 25 | 26 | 27 | 28 | Fluxible Minimal Example 29 | 30 | 31 |
    ${markup}
    32 | 33 | 34 | 35 | 36 | `); 37 | }) 38 | .catch((err) => { 39 | console.error(err); 40 | res.send('Something went wrong'); 41 | }); 42 | }); 43 | 44 | app.listen(8080, () => { 45 | console.log('Listening on http://localhost:8080'); 46 | }); 47 | -------------------------------------------------------------------------------- /examples/doc-site/app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 6 | import debugLib from 'debug'; 7 | import Fluxible from 'fluxible'; 8 | import fetchrPlugin from 'fluxible-plugin-fetchr'; 9 | import devToolsPlugin from 'fluxible-plugin-devtools'; 10 | import queryPlugin from './plugins/queryPlugin'; 11 | import routes from './configs/routes'; 12 | import Application from './components/Application'; 13 | import DocStore from './stores/DocStore'; 14 | import SearchStore from './stores/SearchStore'; 15 | import { RouteStore } from 'fluxible-router'; 16 | 17 | const debug = debugLib('app.js'); 18 | const MyRouteStore = RouteStore.withStaticRoutes(routes); 19 | 20 | const app = new Fluxible({ 21 | component: Application, 22 | componentActionHandler: function (context, payload, done) { 23 | if (payload.err) { 24 | if (payload.err.statusCode === 404) { 25 | debug('component 404 error', payload.err); 26 | } else { 27 | debug('component exception', payload.err); 28 | } 29 | 30 | return; 31 | } 32 | 33 | done(); 34 | }, 35 | }); 36 | 37 | app.plug(queryPlugin()); 38 | app.plug(fetchrPlugin({ xhrPath: '/_api' })); 39 | app.plug(devToolsPlugin()); 40 | 41 | app.registerStore(DocStore); 42 | app.registerStore(MyRouteStore); 43 | app.registerStore(SearchStore); 44 | 45 | export default app; 46 | -------------------------------------------------------------------------------- /docs/community/articles.md: -------------------------------------------------------------------------------- 1 | # Articles and Blogs 2 | 3 | Take a look at some of the articles that our community has written. Edit this 4 | page on GitHub to list yours! 5 | 6 | * 2016-01-05 - [How We Increased Mobile Conversion By 30% 7 | ](https://medium.com/@Art.com/how-we-increased-mobile-revenue-by-30-6721f02744a1#.jhx4z1fej) 8 | * 2015-10-31 - [Moving towards a Universal JavaScript application](http://engineering.carousell.com/universal-javascript/) 9 | * 2015-09-24 - [How to Migrate React to Isomorphic Rendering](https://medium.com/building-coursera/how-to-migrate-react-to-isomorphic-rendering-88347ba653a5) 10 | * 2015-08-27 - [Building a Site Using Isomorphic Flux with Fluxible](http://jacksoncmorgan.com/blog/fluxiblemaster) 11 | * 2015-06-10 - [yahoo/fluxible による SPA + Server Rendering の概観](http://havelog.ayumusato.com/develop/javascript/e675-spa_and_server_rendering_with_fluxible.html) 12 | * 2015-04-14 - [Managing Context In a Fluxible App Using React-Router](http://www.ian-thomas.net/managing-context-in-a-fluxible-app-using-react-router/) 13 | * 2015-03-12 - [How I use fluxible with Hapi](http://danecando.com/how-i-use-fluxible-with-hapi/) 14 | * 2015-02-20 - [Exploring Isomorphic JavaScript](http://nicolashery.com/exploring-isomorphic-javascript/) 15 | * 2014-11-30 - [Isomorphic React + Flux using Yahoo's Fluxible](http://dev.alexishevia.com/2014/11/isomorphic-react-flux-using-yahoos.html) 16 | * 2014-11-06 - [Bringing Flux to the Server](/blog/2014-11-06-bringing-flux-to-the-server.html) 17 | -------------------------------------------------------------------------------- /packages/fluxible-addons-react/docs/api/provideContext.md: -------------------------------------------------------------------------------- 1 | # provideContext 2 | 3 | ```js 4 | import { provideContext } from 'fluxible-addons-react'; 5 | ``` 6 | 7 | `provideContext` is a higher-order component that takes the Fluxible 8 | component contest as prop and provides it to all children of the 9 | wrapped component. 10 | 11 | By default, the `executeAction` and `getStore` methods will be 12 | available in addition to any thing provided by Fluxible plugin that 13 | you have configured. 14 | 15 | ## Example 16 | 17 | The most typical and basic usage of `provideContext` is to wrap your 18 | Application component to ensure that it receives the `getStore` and 19 | `executeAction` methods. 20 | 21 | ```js 22 | const Application = () => { 23 | return
    ...
    ; 24 | } 25 | 26 | export default provideContext(Application); 27 | ``` 28 | 29 | Now when you render the Application component, you can pass in the 30 | component context via the `context` prop and be assured that all 31 | children will have access to through 32 | [`useFluxible`](./useFluxible.md), 33 | [`withFluxible`](./withFluxible.md) or 34 | [`connectToStores`](./connectToStores.md). 35 | 36 | ```js 37 | ReactDOM.renderToString(); 38 | ``` 39 | 40 | If you're using the [`createElementWithContext()` 41 | function](createElementWithContext.md) and you passed a higher-order 42 | `provideContext` component to the Fluxible constructor, then the 43 | `context` prop will automatically be passed in for you. 44 | -------------------------------------------------------------------------------- /examples/create-react-app/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 20 | React App 21 | 22 | 23 | 24 |
    25 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /examples/react-router/client.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | /*global App, document, window */ 6 | 'use strict'; 7 | const React = require('react'); 8 | const ReactDOM = require('react-dom'); 9 | const debug = require('debug'); 10 | const bootstrapDebug = debug('Example'); 11 | const app = require('./app').default; 12 | const dehydratedState = window.App; // Sent from the server 13 | const ReactRouter = require('react-router'); 14 | const { FluxibleComponent } = require('fluxible-addons-react'); 15 | 16 | bootstrapDebug('rehydrating app'); 17 | 18 | function RenderApp(context) { 19 | bootstrapDebug('React Rendering'); 20 | const mountNode = document.getElementById('app'); 21 | ReactDOM.render( 22 | React.createElement( 23 | FluxibleComponent, 24 | { context: context.getComponentContext() }, 25 | React.createElement(ReactRouter.Router, { 26 | routes: context.getComponent(), 27 | history: ReactRouter.browserHistory, 28 | }), 29 | ), 30 | mountNode, 31 | function () { 32 | bootstrapDebug('React Rendered'); 33 | }, 34 | ); 35 | } 36 | 37 | app.rehydrate(dehydratedState, function (err, context) { 38 | if (err) { 39 | throw err; 40 | } 41 | window.debug = debug; 42 | window.context = context; 43 | 44 | RenderApp(context); 45 | }); 46 | -------------------------------------------------------------------------------- /examples/fluxible-router/browser-only/browser-only.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | /* global App, document, window */ 6 | import { render } from 'react-dom'; 7 | import debug from 'debug'; 8 | import Fluxible from 'fluxible'; 9 | import Application from '../components/Application'; 10 | import RouteStore from '../stores/RouteStore'; 11 | import ApplicationStore from '../stores/ApplicationStore'; 12 | import TimeStore from '../stores/TimeStore'; 13 | import PageStore from '../stores/PageStore'; 14 | import { createElementWithContext } from 'fluxible-addons-react'; 15 | import { navigateAction } from 'fluxible-router'; 16 | 17 | const bootstrapDebug = debug('Example'); 18 | const dehydratedState = {}; 19 | 20 | let app = new Fluxible({ 21 | component: Application, 22 | stores: [RouteStore, ApplicationStore, TimeStore, PageStore], 23 | }); 24 | 25 | bootstrapDebug('rehydrating app'); 26 | app.rehydrate(dehydratedState, (err, context) => { 27 | if (err) { 28 | throw err; 29 | } 30 | context.executeAction( 31 | navigateAction, 32 | { url: window.location.pathname, type: 'pageload' }, 33 | () => { 34 | const mountNode = document.getElementById('app'); 35 | window.context = context; 36 | bootstrapDebug('React Rendering'); 37 | render(createElementWithContext(context, {}), mountNode); 38 | }, 39 | ); 40 | }); 41 | -------------------------------------------------------------------------------- /packages/generator-fluxible/tests/unit/test-app.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 6 | const path = require('path'); 7 | const helpers = require('yeoman-test'); 8 | const assert = require('yeoman-assert'); 9 | const TMP_DIR = process.env.TMP_DIR || __dirname; 10 | const tempDir = path.join(TMP_DIR, 'temp'); 11 | 12 | describe('generator-fluxible', function () { 13 | beforeAll(function (done) { 14 | helpers.testDirectory(tempDir, (err) => { 15 | if (err) { 16 | return done(err); 17 | } 18 | 19 | this.lib = helpers.createGenerator( 20 | 'fluxible', 21 | [[require('../../app'), 'fluxible']], 22 | 'fluxy', 23 | { 'skip-install': true }, 24 | ); 25 | done(); 26 | }); 27 | }); 28 | 29 | it('creates files', function () { 30 | return helpers 31 | .run(path.join(__dirname, '../../app')) 32 | .withOptions(test.options) 33 | .withArguments(['fluxy']) 34 | .withPrompts(Object.assign({}, test.prompts, { name: true })) 35 | .then(function () { 36 | assert.file([ 37 | 'package.json', 38 | 'babel.config.js', 39 | 'app.js', 40 | 'components/Application.js', 41 | ]); 42 | }); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /packages/dispatchr/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing Code to `dispatchr` 2 | ------------------------------- 3 | 4 | # How to contribute 5 | First, thanks for taking the time to contribute to our project! The following information provides a guide for making contributions. 6 | 7 | ## Code of Conduct 8 | By participating in this project, you agree to abide by the [Yahoo, Inc. Code of Conduct](Code-of-Conduct.md). Everyone is welcome to submit a pull request or open an issue to improve the documentation, add improvements, or report bugs. 9 | 10 | ## How to Ask a Question 11 | If you simply have a question that needs an answer, [create an issue](https://help.github.com/articles/creating-an-issue/), and label it as a question. 12 | 13 | ### Report a Bug or Request a Feature 14 | If you encounter any bugs while using this software, or want to request a new feature or enhancement, feel free to [create an issue](https://help.github.com/articles/creating-an-issue/) to report it, make sure you add a label to indicate what type of issue it is. 15 | 16 | ### Contribute Code 17 | Pull requests are welcome for bug fixes. If you want to implement something new, please [request a feature first](#report-a-bug-or-request-a-feature) so we can discuss it. 18 | 19 | #### Creating a Pull Request 20 | Please follow [best practices](https://github.com/trein/dev-best-practices/wiki/Git-Commit-Best-Practices) for creating git commits. 21 | 22 | When your code is ready to be submitted, you can [submit a pull request](https://help.github.com/articles/creating-a-pull-request/) to begin the code review process. 23 | -------------------------------------------------------------------------------- /examples/doc-site/assets/css/ie.css: -------------------------------------------------------------------------------- 1 | /** 2 | * "justify" fails so display both as floats (left/right) 3 | */ 4 | #atomic #header #home { 5 | float: left; 6 | } 7 | 8 | #atomic #header ul { 9 | float: right; 10 | } 11 | 12 | /** 13 | * IE7 only 14 | */ 15 | #atomic #header li { 16 | *margin-left: 15px; 17 | } 18 | 19 | /** 20 | * IE8 bug (would not reveal the image because of max-width) 21 | */ 22 | #atomic #header li img { 23 | max-width: none; 24 | } 25 | 26 | /** 27 | * only relevant for small viewport 28 | */ 29 | #atomic #toggleMenuButton { 30 | display: none; 31 | } 32 | 33 | #atomic .innerwrapper { 34 | width: 800px; 35 | margin-left: auto; 36 | margin-right: auto; 37 | padding-left: 0; 38 | padding-right: 0; 39 | } 40 | 41 | /** 42 | * IE7 only 43 | */ 44 | #atomic #aside, 45 | #atomic #main { 46 | display: table-cell; 47 | *display: inline !important; 48 | *zoom: 1; 49 | } 50 | 51 | #atomic #aside { 52 | padding-left: 0; 53 | width: 150px !important; 54 | padding-right: 50px; 55 | } 56 | 57 | #atomic #main { 58 | padding-right: 0; 59 | padding-left: 0; 60 | width: 600px !important; 61 | *width: 580px !important; 62 | } 63 | 64 | /** 65 | * "justify" fails so display both lines as blocks 66 | */ 67 | #atomic #footer small { 68 | display: block !important; 69 | } 70 | 71 | /** 72 | * LOGO 73 | */ 74 | #splash h1 { 75 | width: 640px !important; 76 | height: 92px; 77 | background-image: url(../images/atomic-css-logo.png); 78 | } 79 | #logo { 80 | display: none; 81 | } 82 | -------------------------------------------------------------------------------- /packages/fluxible-addons-react/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing Code to `fluxible` 2 | ------------------------------- 3 | 4 | # How to contribute 5 | First, thanks for taking the time to contribute to our project! The following information provides a guide for making contributions. 6 | 7 | ## Code of Conduct 8 | By participating in this project, you agree to abide by the [Yahoo, Inc. Code of Conduct](Code-of-Conduct.md). Everyone is welcome to submit a pull request or open an issue to improve the documentation, add improvements, or report bugs. 9 | 10 | ## How to Ask a Question 11 | If you simply have a question that needs an answer, [create an issue](https://help.github.com/articles/creating-an-issue/), and label it as a question. 12 | 13 | ### Report a Bug or Request a Feature 14 | If you encounter any bugs while using this software, or want to request a new feature or enhancement, feel free to [create an issue](https://help.github.com/articles/creating-an-issue/) to report it, make sure you add a label to indicate what type of issue it is. 15 | 16 | ### Contribute Code 17 | Pull requests are welcome for bug fixes. If you want to implement something new, please [request a feature first](#report-a-bug-or-request-a-feature) so we can discuss it. 18 | 19 | #### Creating a Pull Request 20 | Please follow [best practices](https://github.com/trein/dev-best-practices/wiki/Git-Commit-Best-Practices) for creating git commits. 21 | 22 | When your code is ready to be submitted, you can [submit a pull request](https://help.github.com/articles/creating-a-pull-request/) to begin the code review process. 23 | -------------------------------------------------------------------------------- /packages/fluxible/docs/api/addons/BaseStore.md: -------------------------------------------------------------------------------- 1 | # BaseStore 2 | 3 | ```js 4 | import BaseStore from 'fluxible/addons/BaseStore'; 5 | ``` 6 | 7 | A base class that you can extend to reduce boilerplate when creating stores. 8 | 9 | ## Built-In Methods 10 | 11 | * `emitChange()` - emits a 'change' event 12 | * `getContext()` - returns the [store context](../FluxibleContext.md#store-context) 13 | * `addChangeListener(callback)` - simple method to add a change listener 14 | * `removeChangeListener(callback)` - removes a change listener 15 | * `shouldDehydrate()` - default implementation that returns true if a `change` event has been emitted 16 | 17 | ## Example 18 | 19 | ```js 20 | class ApplicationStore extends BaseStore { 21 | constructor (dispatcher) { 22 | super(dispatcher); 23 | this.currentPageName = null; 24 | } 25 | 26 | handleReceivePage (payload) { 27 | this.currentPageName = payload.pageName; 28 | this.emitChange(); 29 | } 30 | 31 | getCurrentPageName () { 32 | return this.currentPageName; 33 | } 34 | 35 | // For sending state to the client 36 | dehydrate () { 37 | return { 38 | currentPageName: this.currentPageName 39 | }; 40 | } 41 | 42 | // For rehydrating server state 43 | rehydrate (state) { 44 | this.currentPageName = state.currentPageName; 45 | } 46 | } 47 | 48 | ApplicationStore.storeName = 'ApplicationStore'; 49 | ApplicationStore.handlers = { 50 | 'RECEIVE_PAGE': 'handleReceivePage' 51 | }; 52 | 53 | export default ApplicationStore; 54 | ``` 55 | -------------------------------------------------------------------------------- /packages/generator-fluxible/app/templates/components/Application.js: -------------------------------------------------------------------------------- 1 | /*globals document*/ 2 | 3 | import React from 'react'; 4 | import Nav from './Nav'; 5 | import PropTypes from 'prop-types'; 6 | import ApplicationStore from '../stores/ApplicationStore'; 7 | import { connectToStores, provideContext } from 'fluxible-addons-react'; 8 | import { handleHistory } from 'fluxible-router'; 9 | import pages from '../configs/routes'; 10 | 11 | class Application extends React.Component { 12 | render() { 13 | var Handler = this.props.currentRoute.handler; 14 | 15 | return ( 16 |
    17 |
    20 | ); 21 | } 22 | 23 | componentDidUpdate(prevProps, prevState) { 24 | const newProps = this.props; 25 | if (newProps.pageTitle === prevProps.pageTitle) { 26 | return; 27 | } 28 | document.title = newProps.pageTitle; 29 | } 30 | } 31 | 32 | Application.propTypes = { 33 | currentRoute: PropTypes.object, 34 | pageTitle: PropTypes.string, 35 | }; 36 | 37 | export default provideContext( 38 | handleHistory( 39 | connectToStores( 40 | Application, 41 | [ApplicationStore], 42 | function (context, props) { 43 | var appStore = context.getStore(ApplicationStore); 44 | return { 45 | pageTitle: appStore.getPageTitle(), 46 | }; 47 | }, 48 | ), 49 | ), 50 | ); 51 | -------------------------------------------------------------------------------- /packages/fluxible-addons-react/docs/api/FluxibleComponent.md: -------------------------------------------------------------------------------- 1 | # FluxibleComponent 2 | 3 | ```js 4 | import { FluxibleComponent } from 'fluxible-addons-react; 5 | ``` 6 | 7 | The `FluxibleComponent` is a wrapper component that will provide all 8 | of its children with access to the Fluxible component context. This 9 | should be used to wrap your top level component. It provides access to 10 | the methods on the [component 11 | context](../../../../packages/fluxible/docs/api/Components.md#component-context). 12 | 13 | You can get access to these methods by using [`useFluxible`](./useFluxible.md) hook or 14 | [`withFluxible`](./withFluxible.md) higher-order component. 15 | 16 | ## Usage 17 | 18 | If you have a component that needs access to the 19 | [`ComponentContext`](../../../../packages/fluxible/docs/api/Components.md#component-context) 20 | methods: 21 | 22 | ```js 23 | const Component = () => { 24 | const context = useFluxible(); 25 | const onClick = () => context.executeAction(myAction); 26 | 27 | return