├── .dockerignore ├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .github ├── ISSUE_TEMPLATE │ ├── 1-bug.md │ ├── 2-docs.md │ └── 3-feature-request.md ├── dependabot.yml └── workflows │ ├── nodejs.yml │ └── npm-publish.yml ├── .gitignore ├── .prettierrc ├── .vscode └── settings.json ├── Dockerfile ├── LICENSE ├── README.md ├── TODO.md ├── docker-compose.yml ├── docs └── apis │ ├── README.md │ ├── _media │ └── workflow.jpg │ ├── packages.md │ ├── reactant-cli │ ├── README.md │ └── globals.md │ ├── reactant-di │ ├── README.md │ └── globals.md │ ├── reactant-last-action │ ├── README.md │ └── globals.md │ ├── reactant-model │ ├── README.md │ └── globals.md │ ├── reactant-module │ ├── README.md │ └── globals.md │ ├── reactant-native │ ├── README.md │ └── globals.md │ ├── reactant-redux │ ├── README.md │ └── globals.md │ ├── reactant-router-dom │ ├── README.md │ └── globals.md │ ├── reactant-router-native │ ├── README.md │ └── globals.md │ ├── reactant-router │ ├── README.md │ └── globals.md │ ├── reactant-share │ ├── README.md │ └── globals.md │ ├── reactant-ssr │ ├── README.md │ └── globals.md │ ├── reactant-storage │ ├── README.md │ └── globals.md │ ├── reactant-template │ ├── README.md │ └── globals.md │ ├── reactant-web │ ├── README.md │ └── globals.md │ └── reactant │ ├── README.md │ └── globals.md ├── examples ├── .eslintrc ├── js-counter │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.html │ │ └── index.jsx │ └── webpack.config.js ├── reactant-share-base-coworker │ ├── README.md │ ├── detached-window.html │ ├── global.d.ts │ ├── iframe.html │ ├── index.html │ ├── package.json │ ├── src │ │ ├── app.view.tsx │ │ ├── counter-coworker.ts │ │ ├── counter.view.tsx │ │ ├── coworker.ts │ │ ├── detached-window.ts │ │ ├── iframe.ts │ │ ├── index.ts │ │ ├── proxyCounter.tsx │ │ └── todoList.view.tsx │ ├── tsconfig.json │ └── webpack.config.js ├── reactant-share-hybrid │ ├── README.md │ ├── global.d.ts │ ├── package.json │ ├── src │ │ ├── detached-window.html │ │ ├── detached-window.ts │ │ ├── iframe.html │ │ ├── iframe.ts │ │ ├── index.html │ │ ├── index.ts │ │ └── modules │ │ │ ├── app.view.tsx │ │ │ ├── counter.view.tsx │ │ │ └── todoList.view.tsx │ ├── tsconfig.json │ └── webpack.config.js ├── reactant-share-sharedtab │ ├── README.md │ ├── global.d.ts │ ├── package.json │ ├── src │ │ ├── index.html │ │ └── index.tsx │ ├── tsconfig.json │ └── webpack.config.js ├── reactant-share-sharedworker-coworker │ ├── README.md │ ├── detached-window.html │ ├── global.d.ts │ ├── iframe.html │ ├── index.html │ ├── package.json │ ├── src │ │ ├── app.view.tsx │ │ ├── counter.view.tsx │ │ ├── coworker.ts │ │ ├── detached-window.ts │ │ ├── iframe.ts │ │ ├── index.ts │ │ ├── proxyCounter.tsx │ │ ├── todoList.view.tsx │ │ └── worker.ts │ ├── tsconfig.json │ └── webpack.config.js ├── reactant-share-sharedworker-lazy │ ├── README.md │ ├── detached-window.html │ ├── global.d.ts │ ├── iframe.html │ ├── index.html │ ├── package.json │ ├── src │ │ ├── app.view.tsx │ │ ├── counter.view.tsx │ │ ├── detached-window.ts │ │ ├── iframe.ts │ │ ├── index.ts │ │ ├── lazyModule.ts │ │ ├── style.css │ │ ├── todoList.view.tsx │ │ └── worker.ts │ ├── tsconfig.json │ └── webpack.config.js ├── reactant-share-sharedworker │ ├── README.md │ ├── detached-window.html │ ├── global.d.ts │ ├── iframe.html │ ├── index.html │ ├── package.json │ ├── src │ │ ├── app.view.tsx │ │ ├── counter.view.tsx │ │ ├── detached-window.ts │ │ ├── iframe.ts │ │ ├── index.ts │ │ ├── todoList.view.tsx │ │ └── worker.ts │ ├── tsconfig.json │ └── webpack.config.js ├── reactant-share-webrtc │ ├── README.md │ ├── global.d.ts │ ├── index.html │ ├── other.html │ ├── package.json │ ├── src │ │ ├── app.tsx │ │ ├── index.ts │ │ └── other.ts │ ├── tsconfig.json │ └── webpack.config.js ├── ts-bookstore │ ├── README.md │ ├── global.d.ts │ ├── package.json │ ├── src │ │ ├── components │ │ │ ├── BookItem.tsx │ │ │ └── index.ts │ │ ├── index.html │ │ ├── index.tsx │ │ ├── model │ │ │ └── index.ts │ │ ├── modules │ │ │ ├── books.service.ts │ │ │ ├── comments.service.ts │ │ │ ├── index.ts │ │ │ ├── shoppingCart.service.ts │ │ │ └── users.service.ts │ │ └── views │ │ │ ├── book.view.tsx │ │ │ ├── bookList.view.tsx │ │ │ ├── home.view.tsx │ │ │ ├── index.tsx │ │ │ └── shoppingCart.view.tsx │ ├── tsconfig.json │ └── webpack.config.js ├── ts-counter │ ├── README.md │ ├── global.d.ts │ ├── package.json │ ├── src │ │ ├── index.html │ │ └── index.tsx │ ├── tsconfig.json │ └── webpack.config.js └── ts-vite-counter │ ├── .gitignore │ ├── README.md │ ├── eslint.config.js │ ├── index.html │ ├── package.json │ ├── public │ └── vite.svg │ ├── src │ ├── App.css │ ├── App.tsx │ ├── assets │ │ └── react.svg │ ├── index.css │ ├── main.tsx │ └── vite-env.d.ts │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── globals.d.ts ├── lerna.json ├── logo.svg ├── package.json ├── packages ├── reactant-cli │ ├── README.md │ ├── package.json │ ├── src │ │ ├── generate.ts │ │ ├── index.ts │ │ ├── info.ts │ │ ├── init.ts │ │ └── utils.ts │ ├── templates │ │ ├── service │ │ │ ├── template.service.js │ │ │ ├── template.service.spec.js │ │ │ ├── template.service.spec.ts │ │ │ └── template.service.ts │ │ └── view │ │ │ ├── template.view.jsx │ │ │ ├── template.view.spec.jsx │ │ │ ├── template.view.spec.tsx │ │ │ └── template.view.tsx │ └── test │ │ └── index.test.ts ├── reactant-di │ ├── README.md │ ├── index.ts │ ├── package.json │ ├── src │ │ ├── constants.ts │ │ ├── createContainer.ts │ │ ├── decorators │ │ │ ├── index.ts │ │ │ ├── inject.ts │ │ │ ├── injectable.ts │ │ │ ├── lazy.ts │ │ │ ├── multiInject.ts │ │ │ ├── multiOptional.ts │ │ │ └── optional.ts │ │ ├── forwardRef.ts │ │ ├── index.ts │ │ ├── interfaces.ts │ │ ├── middlewares │ │ │ ├── collector.ts │ │ │ └── index.ts │ │ ├── moduleRef.ts │ │ ├── optional.ts │ │ └── util.ts │ └── test │ │ ├── createContainer.test.ts │ │ ├── decorators │ │ ├── __snapshots__ │ │ │ └── multiInject.test.ts.snap │ │ ├── inject.test.ts │ │ ├── injectable.test.ts │ │ ├── lazy.test.ts │ │ ├── multiInject.test.ts │ │ ├── multiOptional.test.ts │ │ └── optional.test.ts │ │ └── index.test.ts ├── reactant-last-action │ ├── README.md │ ├── index.ts │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── lastAction.ts │ └── test │ │ └── index.test.tsx ├── reactant-model │ ├── README.md │ ├── index.ts │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── model.ts │ └── test │ │ └── index.test.ts ├── reactant-module │ ├── README.md │ ├── index.ts │ ├── package.json │ ├── src │ │ ├── constants │ │ │ ├── index.ts │ │ │ ├── moduleKeys.ts │ │ │ └── reduxKeys.ts │ │ ├── core │ │ │ ├── applyMiddleware.ts │ │ │ ├── createState.ts │ │ │ ├── createStore.ts │ │ │ ├── dispatch.ts │ │ │ ├── getRef.ts │ │ │ ├── handlePlugin.ts │ │ │ ├── index.ts │ │ │ ├── load.ts │ │ │ ├── plugin.ts │ │ │ ├── signal.ts │ │ │ ├── subscribe.ts │ │ │ ├── view.ts │ │ │ └── watch.ts │ │ ├── decorators │ │ │ ├── action.ts │ │ │ ├── autobind.ts │ │ │ ├── computed.ts │ │ │ ├── dynamic.ts │ │ │ ├── index.ts │ │ │ ├── injectable.ts │ │ │ ├── lazy.ts │ │ │ └── state.ts │ │ ├── index.ts │ │ ├── interfaces.ts │ │ └── utils │ │ │ ├── assign.ts │ │ │ ├── compose.ts │ │ │ ├── getStageName.ts │ │ │ ├── index.ts │ │ │ ├── isEqual.ts │ │ │ ├── performer.ts │ │ │ ├── reduxDevToolsCompose.ts │ │ │ └── selector.ts │ └── test │ │ ├── __snapshots__ │ │ └── index.test.ts.snap │ │ ├── core │ │ ├── createState.test.ts │ │ ├── createStore.test.ts │ │ ├── dispatch.test.ts │ │ ├── getRef.test.ts │ │ ├── handlePlugin.test.ts │ │ └── subscriber.test.ts │ │ ├── decorators │ │ ├── action.test.ts │ │ ├── autobind.test.ts │ │ ├── computed.es2015.ts │ │ ├── computed.test.ts │ │ └── state.test.ts │ │ ├── index.test.ts │ │ └── utils │ │ └── reduxDevToolsCompose.test.ts ├── reactant-native │ ├── README.md │ ├── index.ts │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── render.ts │ └── test │ │ └── index.test.ts ├── reactant-redux │ ├── README.md │ ├── index.ts │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── redux.ts │ └── test │ │ └── index.test.ts ├── reactant-router-dom │ ├── README.md │ ├── index.ts │ ├── package.json │ └── src │ │ └── index.ts ├── reactant-router-native │ └── package.json ├── reactant-router │ ├── README.md │ ├── index.ts │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── router.tsx │ └── test │ │ └── index.test.tsx ├── reactant-share │ ├── README.md │ ├── index.ts │ ├── package.json │ ├── src │ │ ├── applyMethod.ts │ │ ├── client.ts │ │ ├── constants.ts │ │ ├── createApp.ts │ │ ├── createTransport.ts │ │ ├── delegate.ts │ │ ├── fork.ts │ │ ├── index.ts │ │ ├── interfaces.ts │ │ ├── lock.ts │ │ ├── mockPairTransports.ts │ │ ├── modules │ │ │ ├── coworker.ts │ │ │ ├── identifierChecker.ts │ │ │ ├── patchesChecker.ts │ │ │ ├── portDetector.ts │ │ │ ├── router.ts │ │ │ └── storage.ts │ │ ├── server.ts │ │ └── utils.ts │ ├── test │ │ ├── MemoryStorage.ts │ │ ├── case.test.ts │ │ ├── checkPatches.test.tsx │ │ ├── coworker.test.tsx │ │ ├── createApp.0.snap.ts │ │ ├── createApp.test.ts │ │ ├── createTransport.test.tsx │ │ ├── index.test.tsx │ │ ├── isolate.test.tsx │ │ ├── router.test.tsx │ │ └── storage.test.tsx │ └── workflow.jpg ├── reactant-ssr │ ├── README.md │ ├── index.ts │ ├── package.json │ ├── src │ │ ├── appView.tsx │ │ ├── createServerApp.tsx │ │ ├── index.ts │ │ └── interfaces.ts │ └── test │ │ └── index.test.tsx ├── reactant-storage │ ├── README.md │ ├── index.ts │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── storage.tsx │ └── test │ │ ├── __snapshots__ │ │ └── index.test.tsx.snap │ │ └── index.test.tsx ├── reactant-template │ ├── README.md │ ├── package.json │ └── templates │ │ ├── shared-tab │ │ ├── javascript │ │ │ ├── template.json │ │ │ └── template │ │ │ │ ├── README.md │ │ │ │ ├── babel.config.json │ │ │ │ ├── gitignore │ │ │ │ ├── jest.json │ │ │ │ ├── src │ │ │ │ ├── app.view.jsx │ │ │ │ ├── counter.service.js │ │ │ │ ├── counter.service.spec.js │ │ │ │ ├── index.html │ │ │ │ └── index.js │ │ │ │ └── webpack.config.js │ │ └── typescript │ │ │ ├── template.json │ │ │ └── template │ │ │ ├── README.md │ │ │ ├── gitignore │ │ │ ├── jest.json │ │ │ ├── src │ │ │ ├── app.view.tsx │ │ │ ├── counter.service.spec.ts │ │ │ ├── counter.service.ts │ │ │ ├── index.html │ │ │ └── index.ts │ │ │ ├── tsconfig.json │ │ │ └── webpack.config.js │ │ ├── shared-worker │ │ ├── javascript │ │ │ ├── template.json │ │ │ └── template │ │ │ │ ├── README.md │ │ │ │ ├── babel.config.json │ │ │ │ ├── gitignore │ │ │ │ ├── jest.json │ │ │ │ ├── src │ │ │ │ ├── app.view.jsx │ │ │ │ ├── counter.service.js │ │ │ │ ├── counter.service.spec.js │ │ │ │ ├── index.html │ │ │ │ ├── index.js │ │ │ │ └── worker.js │ │ │ │ └── webpack.config.js │ │ └── typescript │ │ │ ├── template.json │ │ │ └── template │ │ │ ├── README.md │ │ │ ├── gitignore │ │ │ ├── jest.json │ │ │ ├── src │ │ │ ├── app.view.tsx │ │ │ ├── counter.service.spec.ts │ │ │ ├── counter.service.ts │ │ │ ├── index.html │ │ │ ├── index.ts │ │ │ └── worker.ts │ │ │ ├── tsconfig.json │ │ │ └── webpack.config.js │ │ └── web │ │ ├── javascript │ │ ├── template.json │ │ └── template │ │ │ ├── README.md │ │ │ ├── babel.config.json │ │ │ ├── gitignore │ │ │ ├── jest.json │ │ │ ├── src │ │ │ ├── app.view.jsx │ │ │ ├── counter.service.js │ │ │ ├── counter.service.spec.js │ │ │ ├── index.html │ │ │ └── index.js │ │ │ └── webpack.config.js │ │ └── typescript │ │ ├── template.json │ │ └── template │ │ ├── README.md │ │ ├── gitignore │ │ ├── jest.json │ │ ├── src │ │ ├── app.view.tsx │ │ ├── counter.service.spec.ts │ │ ├── counter.service.ts │ │ ├── index.html │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── webpack.config.js ├── reactant-web │ ├── README.md │ ├── index.ts │ ├── package.json │ └── src │ │ └── index.ts └── reactant │ ├── README.md │ ├── index.ts │ ├── package.json │ ├── src │ ├── batch.ts │ ├── createApp.tsx │ ├── hooks │ │ ├── index.ts │ │ └── useConnector.ts │ ├── index.ts │ ├── interfaces.ts │ └── testBed.ts │ └── test │ ├── createApp.0.snap.tsx │ ├── createApp.test.ts │ ├── integration │ ├── dynamic.test.tsx │ ├── index.test.tsx │ ├── lazy.test.tsx │ ├── load.test.tsx │ └── plugin.test.tsx │ ├── testBed.test.ts │ └── useConnector.test.tsx ├── scripts ├── build.ts ├── jest │ ├── dev.config.json │ ├── prod.config.json │ ├── useDefineForClassFields.config.json │ └── useES2015.config.json ├── performance │ ├── generateTestSourceWithMobx.ts │ ├── generateTestSourceWithPlain.ts │ ├── generateTestSourceWithReactant.ts │ └── index.ts ├── rollup.ts ├── typedoc.ts ├── typescript.ts └── workspaces.ts ├── tsconfig.json ├── website ├── .gitignore ├── README.md ├── babel.config.js ├── blog │ ├── 2020-08-09-reactant-a-framework-for-building-react-web-applications.md │ ├── 2021-10-03-how-to-make-web-application-support-multiple-browser-windows │ │ ├── index.md │ │ └── workflow.jpg │ ├── 2023-12-29-how-to-build-high-performance-front-end-applications-based-on-multi-processing │ │ ├── index.md │ │ └── workflow.png │ └── authors.yml ├── docs │ ├── advanced-guides │ │ ├── dev-workflow.md │ │ ├── di.md │ │ ├── dynamic-modules.md │ │ ├── hooks.md │ │ ├── persistence.md │ │ ├── pluggable.md │ │ ├── routing.md │ │ └── server-side-rendering.md │ ├── api │ │ ├── reactant-di │ │ │ ├── _category_.yml │ │ │ ├── classes │ │ │ │ ├── _category_.yml │ │ │ │ ├── moduleRef.ModuleRef.md │ │ │ │ └── optional.Optional.md │ │ │ ├── index.md │ │ │ └── modules │ │ │ │ ├── _category_.yml │ │ │ │ ├── decorators_inject.md │ │ │ │ ├── decorators_injectable.md │ │ │ │ ├── decorators_lazy.md │ │ │ │ ├── decorators_multiInject.md │ │ │ │ ├── decorators_multiOptional.md │ │ │ │ ├── decorators_optional.md │ │ │ │ ├── forwardRef.md │ │ │ │ ├── moduleRef.md │ │ │ │ └── optional.md │ │ ├── reactant-module │ │ │ ├── _category_.yml │ │ │ ├── classes │ │ │ │ ├── _category_.yml │ │ │ │ ├── core_plugin.PluginModule.md │ │ │ │ └── core_view.ViewModule.md │ │ │ ├── index.md │ │ │ └── modules │ │ │ │ ├── _category_.yml │ │ │ │ ├── core_applyMiddleware.md │ │ │ │ ├── core_createState.md │ │ │ │ ├── core_dispatch.md │ │ │ │ ├── core_load.md │ │ │ │ ├── core_plugin.md │ │ │ │ ├── core_subscribe.md │ │ │ │ ├── core_view.md │ │ │ │ ├── core_watch.md │ │ │ │ ├── decorators_action.md │ │ │ │ ├── decorators_autobind.md │ │ │ │ ├── decorators_computed.md │ │ │ │ ├── decorators_injectable.md │ │ │ │ ├── decorators_lazy.md │ │ │ │ └── decorators_state.md │ │ ├── reactant-router │ │ │ ├── _category_.yml │ │ │ ├── classes │ │ │ │ ├── BaseReactantRouter.md │ │ │ │ ├── Router.md │ │ │ │ └── _category_.yml │ │ │ ├── index.md │ │ │ └── interfaces │ │ │ │ ├── IRouterOptions.md │ │ │ │ ├── RouterState.md │ │ │ │ └── _category_.yml │ │ ├── reactant-share │ │ │ ├── _category_.yml │ │ │ ├── classes │ │ │ │ ├── _category_.yml │ │ │ │ ├── portDetector.PortDetector.md │ │ │ │ ├── router.Router.md │ │ │ │ └── storage.Storage.md │ │ │ ├── index.md │ │ │ ├── interfaces │ │ │ │ ├── _category_.yml │ │ │ │ ├── router.IRouterOptions.md │ │ │ │ └── storage.IStorageOptions.md │ │ │ └── modules │ │ │ │ ├── _category_.yml │ │ │ │ ├── createApp.md │ │ │ │ ├── delegate.md │ │ │ │ ├── fork.md │ │ │ │ ├── portDetector.md │ │ │ │ ├── router.md │ │ │ │ ├── spawn.md │ │ │ │ └── storage.md │ │ ├── reactant-storage │ │ │ ├── _category_.yml │ │ │ ├── classes │ │ │ │ ├── Storage.md │ │ │ │ └── _category_.yml │ │ │ ├── index.md │ │ │ └── interfaces │ │ │ │ ├── IStorageOptions.md │ │ │ │ └── _category_.yml │ │ └── reactant │ │ │ ├── _category_.yml │ │ │ ├── index.md │ │ │ └── modules │ │ │ ├── _category_.yml │ │ │ ├── createApp.md │ │ │ ├── hooks_useConnector.md │ │ │ └── testBed.md │ ├── basic-tutorial │ │ ├── base-di.md │ │ ├── component.md │ │ ├── state-action.md │ │ └── view-module.md │ ├── getting-started │ │ ├── concepts.md │ │ ├── installation.md │ │ ├── react-native-cli.md │ │ └── using-create-react-app.md │ ├── intro.md │ ├── resources │ │ ├── examples.md │ │ ├── faq.md │ │ └── performance.md │ ├── shared-app │ │ ├── img │ │ │ └── workflow.jpg │ │ ├── shared-app- isolated-state.md │ │ ├── shared-app-coworker.md │ │ ├── shared-app-persistence.md │ │ ├── shared-app-routing.md │ │ └── shared-app.md │ └── tooling │ │ ├── cli.md │ │ └── dev-tools.md ├── docusaurus.config.js ├── package.json ├── sidebars.js ├── src │ ├── components │ │ └── HomepageFeatures │ │ │ ├── index.tsx │ │ │ └── styles.module.css │ ├── css │ │ └── custom.css │ └── pages │ │ ├── ParticlesContainer.tsx │ │ ├── index.module.css │ │ ├── index.tsx │ │ └── markdown-page.md ├── static │ ├── .nojekyll │ ├── CNAME │ └── img │ │ ├── favicon.ico │ │ ├── logo.svg │ │ ├── undraw_code_review.svg │ │ ├── undraw_dev_productivity.svg │ │ ├── undraw_docusaurus_mountain.svg │ │ ├── undraw_docusaurus_react.svg │ │ ├── undraw_docusaurus_tree.svg │ │ ├── undraw_monitor.svg │ │ ├── undraw_note_list.svg │ │ ├── undraw_online.svg │ │ ├── undraw_open_source.svg │ │ ├── undraw_operating_system.svg │ │ ├── undraw_preferences.svg │ │ ├── undraw_programmer.svg │ │ ├── undraw_programming.svg │ │ ├── undraw_progressive_app.svg │ │ ├── undraw_react.svg │ │ ├── undraw_researching.svg │ │ └── undraw_tweetstorm.svg └── tsconfig.json └── yarn.lock /.dockerignore: -------------------------------------------------------------------------------- 1 | */node_modules 2 | *.log 3 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | # install EditorConfig for VS Code extension 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | end_of_line = lf 9 | indent_size = 2 10 | indent_style = space 11 | insert_final_newline = true 12 | max_line_length = 80 13 | trim_trailing_whitespace = true 14 | 15 | [*.md] 16 | max_line_length = 0 17 | trim_trailing_whitespace = false 18 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/1-bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🐛 Bug Report 3 | about: Report a reproducible bug for Reactant 4 | labels: bug 5 | --- 6 | 7 | ### Description 8 | 9 | 12 | 13 | ### Minimal Reproduction 14 | 15 | 18 | 19 | ### Version 20 | 21 | 24 | 25 | ### Expected Behavior 26 | 27 | ### Actual Behavior 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/2-docs.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 📜 Documentation 3 | about: Report an issue in Reactant's documentation or https://reactant.js.org/, submit the PR instead. 4 | labels: documentation 5 | --- 6 | 7 | 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/3-feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🚀 Feature Request 3 | about: Suggest a feature for Reactant 4 | labels: discussion 5 | --- 6 | 7 | 10 | 11 | ### Relevant Package 12 | 13 | ### Description 14 | 15 | 18 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Basic dependabot.yml file with 2 | # minimum configuration for two package managers 3 | 4 | version: 2 5 | updates: 6 | # Enable version updates for npm 7 | - package-ecosystem: "npm" 8 | # Look for `package.json` and `lock` files in the `root` directory 9 | directory: "/" 10 | # Check the npm registry for updates every day (weekdays) 11 | schedule: 12 | interval: "daily" 13 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | matrix: 12 | node-version: [18.x, 20.x, 22.x] 13 | 14 | steps: 15 | - uses: actions/checkout@v1 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v1 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | - name: yarn install, build, and test 21 | run: | 22 | yarn install 23 | yarn test 24 | yarn build 25 | yarn test 26 | env: 27 | CI: true 28 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | name: Node.js Package 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | publish-npm: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | contents: read 12 | id-token: write 13 | steps: 14 | - uses: actions/checkout@v3 15 | - uses: actions/setup-node@v3 16 | with: 17 | node-version: '20.x' 18 | registry-url: 'https://registry.npmjs.org' 19 | - run: yarn 20 | - run: yarn build 21 | - run: yarn test 22 | - run: npm run publish --provenance 23 | env: 24 | NODE_AUTH_TOKEN: ${{secrets.NPM_AUTH_TOKEN}} 25 | CI: true 26 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "es5" 4 | } 5 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "esbenp.prettier-vscode", 3 | "[javascript]": { 4 | "editor.defaultFormatter": "esbenp.prettier-vscode" 5 | }, 6 | "typescript.tsdk": "node_modules/typescript/lib", 7 | "cSpell.words": [ 8 | "inversify", 9 | "middlewares", 10 | "persistor", 11 | "unsubscriptions" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts 2 | 3 | WORKDIR /app/website 4 | 5 | EXPOSE 3000 35729 6 | COPY ./docs /app/docs 7 | COPY ./website /app/website 8 | RUN yarn install 9 | 10 | CMD ["yarn", "start"] 11 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | - [x] update API docs 3 | - [x] use Mutative 4 | - [x] fix router state sync checking logic 5 | - [ ] Implementing non-invasive injection for DI 6 | - [ ] support TS 5.0 new decorator(https://github.com/tc39/proposal-decorators), [more detail](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-0.html#differences-with-experimental-legacy-decorators) 7 | - [ ] upgrade inversify v6 8 | - [ ] upgrade react-router v6.22.1 9 | - [ ] upgrade react/react-dom 17.x and 18.x 10 | - [ ] upgrade react-native 11 | - [ ] upgrade redux v5 12 | - [ ] upgrade react-redux v8.1.3 for React 17.x and 18.x 13 | - [ ] support `upgrade` CLI 14 | - [ ] dynamic unloading module 15 | - [ ] improve CLI about `bun` 16 | - [ ] support `vite` 17 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | docusaurus: 5 | build: . 6 | ports: 7 | - 3000:3000 8 | - 35729:35729 9 | volumes: 10 | - ./docs:/app/docs 11 | - ./website/blog:/app/website/blog 12 | - ./website/core:/app/website/core 13 | - ./website/i18n:/app/website/i18n 14 | - ./website/pages:/app/website/pages 15 | - ./website/static:/app/website/static 16 | - ./website/sidebars.json:/app/website/sidebars.json 17 | - ./website/siteConfig.js:/app/website/siteConfig.js 18 | working_dir: /app/website 19 | -------------------------------------------------------------------------------- /docs/apis/_media/workflow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unadlib/reactant/792fd8e29aa214a3e172d279f6ce82960c06ccb0/docs/apis/_media/workflow.jpg -------------------------------------------------------------------------------- /docs/apis/packages.md: -------------------------------------------------------------------------------- 1 | [**Documentation**](README.md) 2 | 3 | *** 4 | 5 | # Documentation 6 | 7 | ## Packages 8 | 9 | - [reactant](reactant/README.md) 10 | - [reactant-cli](reactant-cli/README.md) 11 | - [reactant-di](reactant-di/README.md) 12 | - [reactant-last-action](reactant-last-action/README.md) 13 | - [reactant-model](reactant-model/README.md) 14 | - [reactant-module](reactant-module/README.md) 15 | - [reactant-native](reactant-native/README.md) 16 | - [reactant-redux](reactant-redux/README.md) 17 | - [reactant-router](reactant-router/README.md) 18 | - [reactant-router-dom](reactant-router-dom/README.md) 19 | - [reactant-router-native](reactant-router-native/README.md) 20 | - [reactant-share](reactant-share/README.md) 21 | - [reactant-ssr](reactant-ssr/README.md) 22 | - [reactant-storage](reactant-storage/README.md) 23 | - [reactant-template](reactant-template/README.md) 24 | - [reactant-web](reactant-web/README.md) 25 | -------------------------------------------------------------------------------- /docs/apis/reactant-cli/README.md: -------------------------------------------------------------------------------- 1 | **reactant-cli** 2 | 3 | *** 4 | 5 | # reactant-cli 6 | 7 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 8 | 9 | A command line interface for Reactant 10 | 11 | ## Usage 12 | 13 | * Create a Reactant project: 14 | 15 | ```bash 16 | npx reactant-cli init my-app 17 | ``` 18 | 19 | * Generate a service file: 20 | 21 | ```bash 22 | npx reactant-cli generate service Foo 23 | # or 24 | npx reactant-cli g s FooBarView 25 | ``` 26 | 27 | * Generate a view file: 28 | 29 | ```bash 30 | npx reactant-cli generate view FooBarView 31 | # or 32 | npx reactant-cli g v FooBarView 33 | ``` 34 | 35 | ## Global installation 36 | 37 | We recommend you install `reactant-cli` globally to use it. 38 | 39 | ```bash 40 | npm install -g reactant-cli 41 | ``` 42 | 43 | or you can install `reactant-cli` to your project. 44 | 45 | ```bash 46 | yarn add -D reactant-cli 47 | ``` 48 | 49 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 50 | -------------------------------------------------------------------------------- /docs/apis/reactant-cli/globals.md: -------------------------------------------------------------------------------- 1 | [**reactant-cli**](README.md) 2 | 3 | *** 4 | 5 | # reactant-cli 6 | -------------------------------------------------------------------------------- /docs/apis/reactant-di/README.md: -------------------------------------------------------------------------------- 1 | **reactant-di** 2 | 3 | *** 4 | 5 | # reactant-di 6 | 7 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 8 | 9 | A dependency injection lib for Reactant 10 | 11 | ## Usage 12 | 13 | ```bash 14 | npm install reactant-di 15 | # or 16 | yarn add reactant-di 17 | ``` 18 | 19 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 20 | -------------------------------------------------------------------------------- /docs/apis/reactant-di/globals.md: -------------------------------------------------------------------------------- 1 | [**reactant-di**](README.md) 2 | 3 | *** 4 | 5 | # reactant-di 6 | -------------------------------------------------------------------------------- /docs/apis/reactant-last-action/README.md: -------------------------------------------------------------------------------- 1 | **reactant-last-action** 2 | 3 | *** 4 | 5 | # reactant-last-action 6 | 7 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 8 | 9 | A Reactant plugin for staging last action 10 | 11 | ## Usage 12 | 13 | ```bash 14 | npm install reactant-last-action 15 | # or 16 | yarn add reactant-last-action 17 | ``` 18 | 19 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 20 | -------------------------------------------------------------------------------- /docs/apis/reactant-last-action/globals.md: -------------------------------------------------------------------------------- 1 | [**reactant-last-action**](README.md) 2 | 3 | *** 4 | 5 | # reactant-last-action 6 | -------------------------------------------------------------------------------- /docs/apis/reactant-model/README.md: -------------------------------------------------------------------------------- 1 | **reactant-model** 2 | 3 | *** 4 | 5 | # reactant-model 6 | 7 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 8 | 9 | A model lib for Reactant 10 | 11 | ## Usage 12 | 13 | ```bash 14 | npm install reactant-model 15 | # or 16 | yarn add reactant-model 17 | ``` 18 | 19 | ## Example 20 | 21 | ```js 22 | import { model } from 'reactant-model'; 23 | 24 | const counter = model({ 25 | state: { 26 | count: 0, 27 | }, 28 | actions: { 29 | increase: (num) => (state) => { 30 | state.count += num; 31 | }, 32 | } 33 | }); 34 | ``` 35 | 36 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 37 | -------------------------------------------------------------------------------- /docs/apis/reactant-model/globals.md: -------------------------------------------------------------------------------- 1 | [**reactant-model**](README.md) 2 | 3 | *** 4 | 5 | # reactant-model 6 | -------------------------------------------------------------------------------- /docs/apis/reactant-module/README.md: -------------------------------------------------------------------------------- 1 | **reactant-module** 2 | 3 | *** 4 | 5 | # reactant-module 6 | 7 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 8 | 9 | A module model for Reactant 10 | 11 | ## Usage 12 | 13 | ```bash 14 | npm install reactant-module 15 | # or 16 | yarn add reactant-module 17 | ``` 18 | 19 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 20 | -------------------------------------------------------------------------------- /docs/apis/reactant-module/globals.md: -------------------------------------------------------------------------------- 1 | [**reactant-module**](README.md) 2 | 3 | *** 4 | 5 | # reactant-module 6 | -------------------------------------------------------------------------------- /docs/apis/reactant-native/README.md: -------------------------------------------------------------------------------- 1 | **reactant-native** 2 | 3 | *** 4 | 5 | # reactant-native 6 | 7 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 8 | 9 | A mobile application with react-native for Reactant 10 | 11 | ## Usage 12 | 13 | ```bash 14 | npm install reactant-native 15 | # or 16 | yarn add reactant-native 17 | ``` 18 | 19 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 20 | -------------------------------------------------------------------------------- /docs/apis/reactant-native/globals.md: -------------------------------------------------------------------------------- 1 | [**reactant-native**](README.md) 2 | 3 | *** 4 | 5 | # reactant-native 6 | -------------------------------------------------------------------------------- /docs/apis/reactant-redux/README.md: -------------------------------------------------------------------------------- 1 | **reactant-redux** 2 | 3 | *** 4 | 5 | # reactant-redux 6 | 7 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 8 | 9 | A redux lib for Reactant 10 | 11 | ## Usage 12 | 13 | ```bash 14 | npm install reactant-redux 15 | # or 16 | yarn add reactant-redux 17 | ``` 18 | 19 | ## Example 20 | 21 | ```js 22 | import { redux } from 'reactant-redux'; 23 | 24 | const counter = redux({ 25 | reducers: { 26 | count: (state = 0, { type, payload }) => 27 | type === 'increase' ? state + payload : state, 28 | }, 29 | actions: { 30 | increase: num => dispatch => 31 | dispatch({ 32 | type: 'increase', 33 | payload: num, 34 | }), 35 | }, 36 | }); 37 | ``` 38 | 39 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 40 | -------------------------------------------------------------------------------- /docs/apis/reactant-redux/globals.md: -------------------------------------------------------------------------------- 1 | [**reactant-redux**](README.md) 2 | 3 | *** 4 | 5 | # reactant-redux 6 | -------------------------------------------------------------------------------- /docs/apis/reactant-router-dom/README.md: -------------------------------------------------------------------------------- 1 | **reactant-router-dom** 2 | 3 | *** 4 | 5 | # reactant-router-dom 6 | 7 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 8 | 9 | A react router dom for Reactant 10 | 11 | ## Usage 12 | 13 | ```bash 14 | npm install reactant-router-dom 15 | # or 16 | yarn add reactant-router-dom 17 | ``` 18 | 19 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 20 | -------------------------------------------------------------------------------- /docs/apis/reactant-router-dom/globals.md: -------------------------------------------------------------------------------- 1 | [**reactant-router-dom**](README.md) 2 | 3 | *** 4 | 5 | # reactant-router-dom 6 | -------------------------------------------------------------------------------- /docs/apis/reactant-router-native/globals.md: -------------------------------------------------------------------------------- 1 | [**reactant-router-native**](README.md) 2 | 3 | *** 4 | 5 | # reactant-router-native 6 | -------------------------------------------------------------------------------- /docs/apis/reactant-router/README.md: -------------------------------------------------------------------------------- 1 | **reactant-router** 2 | 3 | *** 4 | 5 | # reactant-router 6 | 7 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 8 | 9 | A router plugin for Reactant 10 | 11 | ## Usage 12 | 13 | ```bash 14 | npm install reactant-router 15 | # or 16 | yarn add reactant-router 17 | ``` 18 | 19 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 20 | -------------------------------------------------------------------------------- /docs/apis/reactant-router/globals.md: -------------------------------------------------------------------------------- 1 | [**reactant-router**](README.md) 2 | 3 | *** 4 | 5 | # reactant-router 6 | -------------------------------------------------------------------------------- /docs/apis/reactant-share/globals.md: -------------------------------------------------------------------------------- 1 | [**reactant-share**](README.md) 2 | 3 | *** 4 | 5 | # reactant-share 6 | -------------------------------------------------------------------------------- /docs/apis/reactant-ssr/globals.md: -------------------------------------------------------------------------------- 1 | [**reactant-ssr**](README.md) 2 | 3 | *** 4 | 5 | # reactant-ssr 6 | -------------------------------------------------------------------------------- /docs/apis/reactant-storage/README.md: -------------------------------------------------------------------------------- 1 | **reactant-storage** 2 | 3 | *** 4 | 5 | # reactant-storage 6 | 7 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 8 | 9 | A persistence storage plugin for Reactant 10 | 11 | ## Usage 12 | 13 | ```bash 14 | npm install reactant-storage 15 | # or 16 | yarn add reactant-storage 17 | ``` 18 | 19 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 20 | -------------------------------------------------------------------------------- /docs/apis/reactant-storage/globals.md: -------------------------------------------------------------------------------- 1 | [**reactant-storage**](README.md) 2 | 3 | *** 4 | 5 | # reactant-storage 6 | -------------------------------------------------------------------------------- /docs/apis/reactant-template/README.md: -------------------------------------------------------------------------------- 1 | **reactant-template** 2 | 3 | *** 4 | 5 | # reactant-storage 6 | 7 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 8 | 9 | A templates collection for Reactant 10 | 11 | ## Usage 12 | 13 | ```bash 14 | npm install -D reactant-template 15 | # or 16 | yarn add -D reactant-template 17 | ``` 18 | 19 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 20 | -------------------------------------------------------------------------------- /docs/apis/reactant-template/globals.md: -------------------------------------------------------------------------------- 1 | [**reactant-template**](README.md) 2 | 3 | *** 4 | 5 | # reactant-template 6 | -------------------------------------------------------------------------------- /docs/apis/reactant-web/README.md: -------------------------------------------------------------------------------- 1 | **reactant-web** 2 | 3 | *** 4 | 5 | # reactant-web 6 | 7 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 8 | 9 | A Web application with react-dom for Reactant 10 | 11 | ## Usage 12 | 13 | ```bash 14 | npm install reactant-web 15 | # or 16 | yarn add reactant-web 17 | ``` 18 | 19 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 20 | -------------------------------------------------------------------------------- /docs/apis/reactant-web/globals.md: -------------------------------------------------------------------------------- 1 | [**reactant-web**](README.md) 2 | 3 | *** 4 | 5 | # reactant-web 6 | -------------------------------------------------------------------------------- /docs/apis/reactant/README.md: -------------------------------------------------------------------------------- 1 | **reactant** 2 | 3 | *** 4 | 5 | # reactant 6 | 7 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 8 | 9 | A framework for building React applications 10 | 11 | ## Usage 12 | 13 | ```bash 14 | npx reactant-cli init my-app 15 | cd my-app 16 | yarn start 17 | ``` 18 | 19 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 20 | -------------------------------------------------------------------------------- /docs/apis/reactant/globals.md: -------------------------------------------------------------------------------- 1 | [**reactant**](README.md) 2 | 3 | *** 4 | 5 | # reactant 6 | -------------------------------------------------------------------------------- /examples/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.eslintrc", 3 | "rules": { 4 | "import/no-extraneous-dependencies": 0 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/js-counter/README.md: -------------------------------------------------------------------------------- 1 | ## Start Up 2 | 3 | Make sure the root directory is running `yarn install && yarn build`. 4 | 5 | ```bash 6 | cd examples/js-counter 7 | yarn install 8 | yarn start 9 | ``` 10 | -------------------------------------------------------------------------------- /examples/js-counter/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/reactant-share-base-coworker/README.md: -------------------------------------------------------------------------------- 1 | ## Start Up 2 | 3 | Make sure the root directory is running `yarn install && yarn build`. 4 | 5 | ```bash 6 | cd examples/reactant-share-base-coworker 7 | yarn install 8 | yarn start 9 | ``` 10 | 11 | open `http://localhost:7000/` & `chrome://inspect/#workers`. 12 | -------------------------------------------------------------------------------- /examples/reactant-share-base-coworker/detached-window.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/reactant-share-base-coworker/global.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | 3 | declare global { 4 | declare const __DEV__: boolean; 5 | interface Window { 6 | __REDUX_DEVTOOLS_EXTENSION_COMPOSE__: any; 7 | app: any; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/reactant-share-base-coworker/iframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/reactant-share-base-coworker/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Index 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/reactant-share-base-coworker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactant-share-base-coworker", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "MIT", 12 | "devDependencies": { 13 | "copy-webpack-plugin": "^11.0.0", 14 | "node-polyfill-webpack-plugin": "^2.0.1", 15 | "ts-loader": "^9.4.1", 16 | "typescript": "^5.4.5", 17 | "webpack": "^5.74.0", 18 | "webpack-cli": "^4.10.0", 19 | "webpack-dev-server": "^4.11.1" 20 | }, 21 | "dependencies": { 22 | "localforage": "^1.10.0", 23 | "react": "^17.0.2" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/reactant-share-base-coworker/src/detached-window.ts: -------------------------------------------------------------------------------- 1 | import { render } from 'reactant-web'; 2 | import { createSharedApp } from 'reactant-share'; 3 | import { TodoListView } from './todoList.view'; 4 | 5 | createSharedApp({ 6 | modules: [ 7 | { 8 | provide: 'TodoListViewOptions', 9 | useValue: { 10 | isDetachedWindow: true, 11 | }, 12 | }, 13 | ], 14 | main: TodoListView, 15 | render, 16 | share: { 17 | name: 'SharedWorkerApp', 18 | type: 'Base', 19 | workerURL: 'worker.bundle.js', 20 | enablePatchesFilter: true, 21 | }, 22 | }).then((app) => { 23 | console.log(app, '===='); 24 | (window as any).app = app; 25 | app.bootstrap(document.getElementById('app')); 26 | }); 27 | -------------------------------------------------------------------------------- /examples/reactant-share-base-coworker/src/iframe.ts: -------------------------------------------------------------------------------- 1 | import { render } from 'reactant-web'; 2 | import { 3 | createSharedApp, 4 | RouterOptions, 5 | createHashHistory, 6 | IRouterOptions, 7 | } from 'reactant-share'; 8 | import { CounterView } from './counter.view'; 9 | 10 | createSharedApp({ 11 | modules: [ 12 | { 13 | provide: RouterOptions, 14 | useValue: { 15 | createHistory: () => createHashHistory(), 16 | } as IRouterOptions, 17 | }, 18 | ], 19 | main: CounterView, 20 | render, 21 | share: { 22 | name: 'BaseWorkerApp', 23 | type: 'Base', 24 | workerURL: 'worker.bundle.js', 25 | }, 26 | }).then((app) => { 27 | console.log(app, '===='); 28 | window.app = app; 29 | app.bootstrap(document.getElementById('app')); 30 | }); 31 | -------------------------------------------------------------------------------- /examples/reactant-share-base-coworker/src/proxyCounter.tsx: -------------------------------------------------------------------------------- 1 | import { injectable, action, state, getCoworker, subscribe } from 'reactant-share'; 2 | 3 | @injectable({ 4 | name: 'ProxyCounter', 5 | }) 6 | export class ProxyCounter { 7 | constructor() { 8 | subscribe(this, () => { 9 | console.log('coworker:', getCoworker(this)?.name); 10 | }); 11 | } 12 | 13 | @state 14 | count = 0; 15 | 16 | @action 17 | increase() { 18 | console.log('increase', getCoworker(this)); 19 | this.count += 1; 20 | } 21 | 22 | @action 23 | decrease() { 24 | console.log('decrease'); 25 | this.count -= 1; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/reactant-share-base-coworker/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "reactant": ["../../node_modules/reactant"], 7 | "reactant-web": ["../../node_modules/reactant-web"], 8 | "reactant-share": ["../../node_modules/reactant-share"], 9 | "reactant-storage": ["../../node_modules/reactant-storage"], 10 | "reactant-router": ["../../node_modules/reactant-router"] 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/reactant-share-hybrid/README.md: -------------------------------------------------------------------------------- 1 | ## Start Up 2 | 3 | Make sure the root directory is running `yarn install && yarn build`. 4 | 5 | ```bash 6 | cd examples/reactant-share-hybrid 7 | yarn install 8 | yarn start 9 | ``` 10 | -------------------------------------------------------------------------------- /examples/reactant-share-hybrid/global.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | 3 | declare global { 4 | declare const __DEV__: boolean; 5 | interface Window { 6 | __REDUX_DEVTOOLS_EXTENSION_COMPOSE__: any; 7 | app: any; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/reactant-share-hybrid/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactant-share-hybrid", 3 | "private": true, 4 | "version": "1.0.0", 5 | "description": "A shared-tab hybrid example for reactant-share", 6 | "main": "index.js", 7 | "scripts": { 8 | "start": "webpack-dev-server", 9 | "build": "webpack" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "copy-webpack-plugin": "^11.0.0", 16 | "node-polyfill-webpack-plugin": "^2.0.1", 17 | "ts-loader": "^9.4.1", 18 | "typescript": "^5.4.5", 19 | "webpack": "^5.74.0", 20 | "webpack-cli": "^4.10.0", 21 | "webpack-dev-server": "^4.11.1" 22 | }, 23 | "dependencies": { 24 | "localforage": "^1.10.0", 25 | "react": "^16.12.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/reactant-share-hybrid/src/detached-window.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/reactant-share-hybrid/src/detached-window.ts: -------------------------------------------------------------------------------- 1 | import { render } from 'reactant-web'; 2 | import { createSharedApp } from 'reactant-share'; 3 | import { TodoListView } from './modules/todoList.view'; 4 | 5 | createSharedApp({ 6 | modules: [ 7 | { 8 | provide: 'TodoListViewOptions', 9 | useValue: { 10 | isDetachedWindow: true, 11 | }, 12 | }, 13 | ], 14 | main: TodoListView, 15 | render, 16 | share: { 17 | name: 'SharedApp', 18 | type: 'SharedTab', 19 | port: 'client', 20 | enablePatchesFilter: true, 21 | }, 22 | }).then((app) => { 23 | console.log(app, '===='); 24 | window.app = app; 25 | app.bootstrap(document.getElementById('app')); 26 | }); 27 | -------------------------------------------------------------------------------- /examples/reactant-share-hybrid/src/iframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/reactant-share-hybrid/src/iframe.ts: -------------------------------------------------------------------------------- 1 | import { render } from 'reactant-web'; 2 | import { 3 | createSharedApp, 4 | RouterOptions, 5 | createHashHistory, 6 | IRouterOptions, 7 | } from 'reactant-share'; 8 | import { CounterView } from './modules/counter.view'; 9 | 10 | createSharedApp({ 11 | modules: [ 12 | { 13 | provide: RouterOptions, 14 | useValue: { 15 | createHistory: () => createHashHistory(), 16 | } as IRouterOptions, 17 | }, 18 | ], 19 | main: CounterView, 20 | render, 21 | share: { 22 | name: 'SharedApp', 23 | type: 'SharedTab', 24 | port: 'client', 25 | portName: 26 | globalThis.location.pathname === '/index.html' ? 'other' : 'default', 27 | }, 28 | }).then((app) => { 29 | console.log(app, '===='); 30 | window.app = app; 31 | app.bootstrap(document.getElementById('app')); 32 | }); 33 | -------------------------------------------------------------------------------- /examples/reactant-share-hybrid/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/reactant-share-hybrid/src/modules/counter.view.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | ViewModule, 4 | injectable, 5 | useConnector, 6 | action, 7 | state, 8 | delegate, 9 | } from 'reactant-share'; 10 | 11 | @injectable({ 12 | name: 'counterView', 13 | }) 14 | export class CounterView extends ViewModule { 15 | constructor() { 16 | super(); 17 | } 18 | 19 | name = 'counter'; 20 | 21 | path = '/counter'; 22 | 23 | @state 24 | count = 0; 25 | 26 | @action 27 | increase() { 28 | this.count += 1; 29 | } 30 | 31 | @action 32 | decrease() { 33 | this.count -= 1; 34 | } 35 | 36 | component(this: CounterView) { 37 | const count = useConnector(() => this.count); 38 | return ( 39 | <> 40 | 43 |
{count}
44 | 47 | 48 | ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /examples/reactant-share-hybrid/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "reactant": ["../../node_modules/reactant"], 7 | "reactant-web": ["../../node_modules/reactant-web"], 8 | "reactant-share": ["../../node_modules/reactant-share"], 9 | "reactant-storage": ["../../node_modules/reactant-storage"], 10 | "reactant-router": ["../../node_modules/reactant-router"] 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedtab/README.md: -------------------------------------------------------------------------------- 1 | ## Start Up 2 | 3 | Make sure the root directory is running `yarn install && yarn build`. 4 | 5 | ```bash 6 | cd examples/reactant-share-sharedtab 7 | yarn install 8 | yarn start 9 | ``` 10 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedtab/global.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | 3 | declare global { 4 | declare const __DEV__: boolean; 5 | interface Window { 6 | __REDUX_DEVTOOLS_EXTENSION_COMPOSE__: any; 7 | app: any; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedtab/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactant-share-sharedtab", 3 | "private": true, 4 | "version": "1.0.0", 5 | "description": "A shared-tab example for reactant-share", 6 | "main": "index.js", 7 | "scripts": { 8 | "start": "webpack-dev-server", 9 | "build": "webpack" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "copy-webpack-plugin": "^11.0.0", 16 | "node-polyfill-webpack-plugin": "^2.0.1", 17 | "ts-loader": "^9.4.1", 18 | "typescript": "^5.4.5", 19 | "webpack": "^5.74.0", 20 | "webpack-cli": "^4.10.0", 21 | "webpack-dev-server": "^4.11.1" 22 | }, 23 | "dependencies": { 24 | "react": "^16.12.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedtab/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedtab/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "reactant": ["../../node_modules/reactant"], 7 | "reactant-web": ["../../node_modules/reactant-web"], 8 | "reactant-share": ["../../node_modules/reactant-share"], 9 | "reactant-storage": ["../../node_modules/reactant-storage"], 10 | "reactant-router": ["../../node_modules/reactant-router"] 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-coworker/README.md: -------------------------------------------------------------------------------- 1 | ## Start Up 2 | 3 | Make sure the root directory is running `yarn install && yarn build`. 4 | 5 | ```bash 6 | cd examples/reactant-share-sharedworker-coworker 7 | yarn install 8 | yarn start 9 | ``` 10 | 11 | open `http://localhost:7000/` & `chrome://inspect/#workers`. 12 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-coworker/detached-window.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-coworker/global.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | 3 | declare global { 4 | declare const __DEV__: boolean; 5 | interface Window { 6 | __REDUX_DEVTOOLS_EXTENSION_COMPOSE__: any; 7 | app: any; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-coworker/iframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-coworker/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Index 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-coworker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactant-share-sharedworker-coworker", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "MIT", 12 | "devDependencies": { 13 | "copy-webpack-plugin": "^11.0.0", 14 | "node-polyfill-webpack-plugin": "^2.0.1", 15 | "ts-loader": "^9.4.1", 16 | "typescript": "^5.4.5", 17 | "webpack": "^5.74.0", 18 | "webpack-cli": "^4.10.0", 19 | "webpack-dev-server": "^4.11.1" 20 | }, 21 | "dependencies": { 22 | "localforage": "^1.10.0", 23 | "react": "^17.0.2" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-coworker/src/detached-window.ts: -------------------------------------------------------------------------------- 1 | import { render } from 'reactant-web'; 2 | import { createSharedApp } from 'reactant-share'; 3 | import { TodoListView } from './todoList.view'; 4 | 5 | createSharedApp({ 6 | modules: [ 7 | { 8 | provide: 'TodoListViewOptions', 9 | useValue: { 10 | isDetachedWindow: true, 11 | }, 12 | }, 13 | ], 14 | main: TodoListView, 15 | render, 16 | share: { 17 | name: 'SharedWorkerApp', 18 | type: 'SharedWorker', 19 | port: 'client', 20 | workerURL: 'worker.bundle.js', 21 | enablePatchesFilter: true, 22 | }, 23 | }).then((app) => { 24 | console.log(app, '===='); 25 | (window as any).app = app; 26 | app.bootstrap(document.getElementById('app')); 27 | }); 28 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-coworker/src/iframe.ts: -------------------------------------------------------------------------------- 1 | import { render } from 'reactant-web'; 2 | import { 3 | createSharedApp, 4 | RouterOptions, 5 | createHashHistory, 6 | IRouterOptions, 7 | } from 'reactant-share'; 8 | import { CounterView } from './counter.view'; 9 | 10 | createSharedApp({ 11 | modules: [ 12 | { 13 | provide: RouterOptions, 14 | useValue: { 15 | createHistory: () => createHashHistory(), 16 | } as IRouterOptions, 17 | }, 18 | ], 19 | main: CounterView, 20 | render, 21 | share: { 22 | name: 'SharedWorkerApp', 23 | port: 'client', 24 | type: 'SharedWorker', 25 | workerURL: 'worker.bundle.js', 26 | portName: 27 | globalThis.location.pathname === '/index.html' ? 'other' : 'default', 28 | }, 29 | }).then((app) => { 30 | console.log(app, '===='); 31 | window.app = app; 32 | app.bootstrap(document.getElementById('app')); 33 | }); 34 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-coworker/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "reactant": ["../../node_modules/reactant"], 7 | "reactant-web": ["../../node_modules/reactant-web"], 8 | "reactant-share": ["../../node_modules/reactant-share"], 9 | "reactant-storage": ["../../node_modules/reactant-storage"], 10 | "reactant-router": ["../../node_modules/reactant-router"] 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-lazy/README.md: -------------------------------------------------------------------------------- 1 | ## Start Up 2 | 3 | Make sure the root directory is running `yarn install && yarn build`. 4 | 5 | ```bash 6 | cd examples/reactant-share-sharedworker 7 | yarn install 8 | yarn start 9 | ``` 10 | 11 | open `http://localhost:7000/` & `chrome://inspect/#workers`. 12 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-lazy/detached-window.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-lazy/global.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-var */ 2 | /* eslint-disable vars-on-top */ 3 | export {}; 4 | 5 | declare global { 6 | declare const __DEV__: boolean; 7 | declare const self: { app: any }; 8 | interface Window { 9 | __REDUX_DEVTOOLS_EXTENSION_COMPOSE__: any; 10 | app: any; 11 | } 12 | 13 | var __worker__: SharedWorker; 14 | 15 | declare module '*.css' { 16 | export default {} as Record; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-lazy/iframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-lazy/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Index 7 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-lazy/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactant-share-sharedworker-lazy", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "MIT", 12 | "devDependencies": { 13 | "copy-webpack-plugin": "^11.0.0", 14 | "node-polyfill-webpack-plugin": "^2.0.1", 15 | "ts-loader": "^9.4.1", 16 | "typescript": "^5.4.5", 17 | "webpack": "^5.74.0", 18 | "webpack-cli": "^4.10.0", 19 | "webpack-dev-server": "^4.11.1" 20 | }, 21 | "dependencies": { 22 | "css-loader": "^6.7.3", 23 | "html-inline-script-webpack-plugin": "^3.1.0", 24 | "html-webpack-plugin": "^5.5.0", 25 | "localforage": "^1.10.0", 26 | "react": "^17.0.2", 27 | "style-loader": "^3.3.1" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-lazy/src/counter.view.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | ViewModule, 4 | injectable, 5 | useConnector, 6 | action, 7 | state, 8 | delegate, 9 | } from 'reactant-share'; 10 | 11 | @injectable({ 12 | name: 'counterView', 13 | }) 14 | export class CounterView extends ViewModule { 15 | constructor() { 16 | super(); 17 | } 18 | 19 | name = 'counter'; 20 | 21 | path = '/counter'; 22 | 23 | @state 24 | count = 0; 25 | 26 | @action 27 | increase() { 28 | this.count += 1; 29 | } 30 | 31 | @action 32 | decrease() { 33 | this.count -= 1; 34 | } 35 | 36 | component(this: CounterView) { 37 | const count = useConnector(() => this.count); 38 | return ( 39 | <> 40 | 43 |
{count}
44 | 47 | 48 | ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-lazy/src/detached-window.ts: -------------------------------------------------------------------------------- 1 | import { render } from 'reactant-web'; 2 | import { createSharedApp } from 'reactant-share'; 3 | import { TodoListView } from './todoList.view'; 4 | 5 | createSharedApp({ 6 | modules: [ 7 | { 8 | provide: 'TodoListViewOptions', 9 | useValue: { 10 | isDetachedWindow: true, 11 | }, 12 | }, 13 | ], 14 | main: TodoListView, 15 | render, 16 | share: { 17 | name: 'SharedWorkerApp', 18 | type: 'SharedWorker', 19 | port: 'client', 20 | workerURL: 'worker.bundle.js', 21 | enablePatchesFilter: true, 22 | }, 23 | }).then((app) => { 24 | console.log(app, '===='); 25 | window.app = app; 26 | app.bootstrap(document.getElementById('app')); 27 | }); 28 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-lazy/src/iframe.ts: -------------------------------------------------------------------------------- 1 | import { render } from 'reactant-web'; 2 | import { 3 | createSharedApp, 4 | RouterOptions, 5 | createHashHistory, 6 | IRouterOptions, 7 | } from 'reactant-share'; 8 | import { CounterView } from './counter.view'; 9 | 10 | createSharedApp({ 11 | modules: [ 12 | { 13 | provide: RouterOptions, 14 | useValue: { 15 | createHistory: () => createHashHistory(), 16 | } as IRouterOptions, 17 | }, 18 | ], 19 | main: CounterView, 20 | render, 21 | share: { 22 | name: 'SharedWorkerApp', 23 | port: 'client', 24 | type: 'SharedWorker', 25 | workerURL: 'worker.bundle.js', 26 | portName: 27 | globalThis.location.pathname === '/index.html' ? 'other' : 'default', 28 | }, 29 | }).then((app) => { 30 | console.log(app, '===='); 31 | window.app = app; 32 | app.bootstrap(document.getElementById('app')); 33 | }); 34 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-lazy/src/lazyModule.ts: -------------------------------------------------------------------------------- 1 | export const fn = () => { 2 | console.log('this is a lazy module'); 3 | }; 4 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-lazy/src/style.css: -------------------------------------------------------------------------------- 1 | .button { 2 | color: #000; 3 | } 4 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-lazy/src/worker.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-restricted-globals */ 2 | import { 3 | createSharedApp, 4 | Router, 5 | Storage, 6 | StorageOptions, 7 | IStorageOptions, 8 | RouterOptions, 9 | createHashHistory, 10 | IRouterOptions, 11 | } from 'reactant-share'; 12 | import localForage from 'localforage'; 13 | import { AppView } from './app.view'; 14 | 15 | createSharedApp({ 16 | modules: [ 17 | Router, 18 | { 19 | provide: RouterOptions, 20 | useValue: { 21 | createHistory: () => createHashHistory(), 22 | } as IRouterOptions, 23 | }, 24 | Storage, 25 | { 26 | provide: StorageOptions, 27 | useValue: { 28 | storage: localForage, 29 | loading: 'loading', 30 | } as IStorageOptions, 31 | }, 32 | ], 33 | main: AppView, 34 | render: () => { 35 | // 36 | }, 37 | share: { 38 | name: 'SharedWorkerApp', 39 | port: 'server', 40 | type: 'SharedWorker', 41 | }, 42 | }).then((app) => { 43 | console.log(app, '===='); 44 | self.app = app; 45 | }); 46 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker-lazy/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "reactant": ["../../node_modules/reactant"], 7 | "reactant-web": ["../../node_modules/reactant-web"], 8 | "reactant-share": ["../../node_modules/reactant-share"], 9 | "reactant-storage": ["../../node_modules/reactant-storage"], 10 | "reactant-router": ["../../node_modules/reactant-router"] 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker/README.md: -------------------------------------------------------------------------------- 1 | ## Start Up 2 | 3 | Make sure the root directory is running `yarn install && yarn build`. 4 | 5 | ```bash 6 | cd examples/reactant-share-sharedworker 7 | yarn install 8 | yarn start 9 | ``` 10 | 11 | open `http://localhost:7000/` & `chrome://inspect/#workers`. 12 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker/detached-window.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker/global.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | 3 | declare global { 4 | declare const __DEV__: boolean; 5 | interface Window { 6 | __REDUX_DEVTOOLS_EXTENSION_COMPOSE__: any; 7 | app: any; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker/iframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Index 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactant-share-sharedworker", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "MIT", 12 | "devDependencies": { 13 | "copy-webpack-plugin": "^11.0.0", 14 | "node-polyfill-webpack-plugin": "^2.0.1", 15 | "ts-loader": "^9.4.1", 16 | "typescript": "^5.4.5", 17 | "webpack": "^5.74.0", 18 | "webpack-cli": "^4.10.0", 19 | "webpack-dev-server": "^4.11.1" 20 | }, 21 | "dependencies": { 22 | "localforage": "^1.10.0", 23 | "react": "^17.0.2" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker/src/counter.view.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | ViewModule, 4 | injectable, 5 | useConnector, 6 | action, 7 | state, 8 | delegate, 9 | } from 'reactant-share'; 10 | 11 | @injectable({ 12 | name: 'counterView', 13 | }) 14 | export class CounterView extends ViewModule { 15 | constructor() { 16 | super(); 17 | } 18 | 19 | name = 'counter'; 20 | 21 | path = '/counter'; 22 | 23 | @state 24 | count = 0; 25 | 26 | @action 27 | increase() { 28 | this.count += 1; 29 | } 30 | 31 | @action 32 | decrease() { 33 | this.count -= 1; 34 | } 35 | 36 | component(this: CounterView) { 37 | const count = useConnector(() => this.count); 38 | return ( 39 | <> 40 | 43 |
{count}
44 | 47 | 48 | ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker/src/detached-window.ts: -------------------------------------------------------------------------------- 1 | import { render } from 'reactant-web'; 2 | import { createSharedApp } from 'reactant-share'; 3 | import { TodoListView } from './todoList.view'; 4 | 5 | createSharedApp({ 6 | modules: [ 7 | { 8 | provide: 'TodoListViewOptions', 9 | useValue: { 10 | isDetachedWindow: true, 11 | }, 12 | }, 13 | ], 14 | main: TodoListView, 15 | render, 16 | share: { 17 | name: 'SharedWorkerApp', 18 | type: 'SharedWorker', 19 | port: 'client', 20 | workerURL: 'worker.bundle.js', 21 | enablePatchesFilter: true, 22 | }, 23 | }).then((app) => { 24 | console.log(app, '===='); 25 | (window as any).app = app; 26 | app.bootstrap(document.getElementById('app')); 27 | }); 28 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker/src/iframe.ts: -------------------------------------------------------------------------------- 1 | import { render } from 'reactant-web'; 2 | import { 3 | createSharedApp, 4 | RouterOptions, 5 | createHashHistory, 6 | IRouterOptions, 7 | } from 'reactant-share'; 8 | import { CounterView } from './counter.view'; 9 | 10 | createSharedApp({ 11 | modules: [ 12 | { 13 | provide: RouterOptions, 14 | useValue: { 15 | createHistory: () => createHashHistory(), 16 | } as IRouterOptions, 17 | }, 18 | ], 19 | main: CounterView, 20 | render, 21 | share: { 22 | name: 'SharedWorkerApp', 23 | port: 'client', 24 | type: 'SharedWorker', 25 | workerURL: 'worker.bundle.js', 26 | portName: 27 | globalThis.location.pathname === '/index.html' ? 'other' : 'default', 28 | }, 29 | }).then((app) => { 30 | console.log(app, '===='); 31 | window.app = app; 32 | app.bootstrap(document.getElementById('app')); 33 | }); 34 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker/src/worker.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-restricted-globals */ 2 | import { 3 | createSharedApp, 4 | Router, 5 | Storage, 6 | StorageOptions, 7 | IStorageOptions, 8 | RouterOptions, 9 | createHashHistory, 10 | IRouterOptions, 11 | } from 'reactant-share'; 12 | import localForage from 'localforage'; 13 | import { AppView } from './app.view'; 14 | 15 | createSharedApp({ 16 | modules: [ 17 | Router, 18 | { 19 | provide: RouterOptions, 20 | useValue: { 21 | createHistory: () => createHashHistory(), 22 | } as IRouterOptions, 23 | }, 24 | Storage, 25 | { 26 | provide: StorageOptions, 27 | useValue: { 28 | storage: localForage, 29 | loading: 'loading', 30 | } as IStorageOptions, 31 | }, 32 | ], 33 | main: AppView, 34 | render: () => { 35 | // 36 | }, 37 | share: { 38 | name: 'SharedWorkerApp', 39 | port: 'server', 40 | type: 'SharedWorker', 41 | }, 42 | }).then((app) => { 43 | console.log(app, '===='); 44 | self.app = app; 45 | }); 46 | -------------------------------------------------------------------------------- /examples/reactant-share-sharedworker/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "reactant": ["../../node_modules/reactant"], 7 | "reactant-web": ["../../node_modules/reactant-web"], 8 | "reactant-share": ["../../node_modules/reactant-share"], 9 | "reactant-storage": ["../../node_modules/reactant-storage"], 10 | "reactant-router": ["../../node_modules/reactant-router"] 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/reactant-share-webrtc/README.md: -------------------------------------------------------------------------------- 1 | ## Start Up 2 | 3 | Make sure the root directory is running `yarn install && yarn build`. 4 | 5 | ```bash 6 | cd examples/reactant-share-webrtc 7 | yarn install 8 | yarn start 9 | ``` 10 | 11 | Open `http://localhost:7000/` and `http://127.0.0.1:700/other.html`, and manually connect two peers. 12 | -------------------------------------------------------------------------------- /examples/reactant-share-webrtc/global.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | 3 | declare global { 4 | declare const __DEV__: boolean; 5 | interface Window { 6 | __REDUX_DEVTOOLS_EXTENSION_COMPOSE__: any; 7 | app: any; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/reactant-share-webrtc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | main tab 7 | 8 | 9 |
10 |
11 | 12 | 13 |
14 |

15 |     
16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /examples/reactant-share-webrtc/other.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | other tab 7 | 8 | 9 |
10 |
11 | 12 | 13 |
14 |

15 |     
16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /examples/reactant-share-webrtc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactant-share-webrtc", 3 | "private": true, 4 | "version": "1.0.0", 5 | "description": "A base example with WebRTC for reactant-share", 6 | "main": "index.js", 7 | "scripts": { 8 | "start": "webpack-dev-server", 9 | "build": "webpack" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "@types/simple-peer": "^9.6.0", 16 | "copy-webpack-plugin": "^11.0.0", 17 | "node-polyfill-webpack-plugin": "^2.0.1", 18 | "ts-loader": "^9.4.1", 19 | "typescript": "^5.4.5", 20 | "webpack": "^5.74.0", 21 | "webpack-cli": "^4.10.0", 22 | "webpack-dev-server": "^4.11.1" 23 | }, 24 | "dependencies": { 25 | "simple-peer": "^9.7.2" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/reactant-share-webrtc/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "reactant": ["../../node_modules/reactant"], 7 | "reactant-web": ["../../node_modules/reactant-web"], 8 | "reactant-share": ["../../node_modules/reactant-share"], 9 | "reactant-storage": ["../../node_modules/reactant-storage"], 10 | "reactant-router": ["../../node_modules/reactant-router"] 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/ts-bookstore/README.md: -------------------------------------------------------------------------------- 1 | ## Start Up 2 | 3 | Make sure the root directory is running `yarn install && yarn build`. 4 | 5 | ```bash 6 | cd examples/ts-bookstore 7 | yarn 8 | yarn start 9 | ``` 10 | -------------------------------------------------------------------------------- /examples/ts-bookstore/global.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | 3 | declare global { 4 | declare const __DEV__: boolean; 5 | interface Window { 6 | __REDUX_DEVTOOLS_EXTENSION_COMPOSE__: any; 7 | app: any; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/ts-bookstore/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ts-bookstore", 3 | "private": true, 4 | "version": "1.0.0", 5 | "description": "A bookstore example for Reactant", 6 | "main": "index.js", 7 | "scripts": { 8 | "start": "webpack-dev-server", 9 | "build": "webpack" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "copy-webpack-plugin": "^11.0.0", 16 | "node-polyfill-webpack-plugin": "^2.0.1", 17 | "ts-loader": "^9.4.1", 18 | "typescript": "^5.4.5", 19 | "webpack": "^5.74.0", 20 | "webpack-cli": "^4.10.0", 21 | "webpack-dev-server": "^4.11.1" 22 | }, 23 | "dependencies": { 24 | "localforage": "^1.10.0", 25 | "normalizr": "^3.6.0", 26 | "react": "^16.12.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/ts-bookstore/src/components/BookItem.tsx: -------------------------------------------------------------------------------- 1 | import React, { FunctionComponent } from 'react'; 2 | import { Link } from 'reactant-web'; 3 | import { IBook } from '../model'; 4 | 5 | export const BookItem: FunctionComponent< 6 | Pick & { link?: string } 7 | > = ({ name, price, count, link }) => { 8 | const bookName = link ? ( 9 | 10 | Book: 11 | {name} 12 | 13 | ) : ( 14 | 15 | Book: 16 | {name} 17 | 18 | ); 19 | return ( 20 |

21 | {bookName} 22 | 23 | Price: 24 | {price} 25 | 26 | 27 | Count: 28 | {count} 29 | 30 |

31 | ); 32 | }; 33 | -------------------------------------------------------------------------------- /examples/ts-bookstore/src/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './BookItem'; 2 | -------------------------------------------------------------------------------- /examples/ts-bookstore/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/ts-bookstore/src/model/index.ts: -------------------------------------------------------------------------------- 1 | export interface IBook { 2 | id: string; 3 | name: string; 4 | count: number; 5 | price: number; 6 | comments: T[]; 7 | } 8 | 9 | export type IBooks = Record; 10 | 11 | export interface IComment { 12 | id: string; 13 | content: string; 14 | user: T; 15 | } 16 | 17 | export type IComments = Record; 18 | 19 | export interface IUser { 20 | id: string; 21 | username: string; 22 | } 23 | 24 | export type IUsers = Record; 25 | -------------------------------------------------------------------------------- /examples/ts-bookstore/src/modules/comments.service.ts: -------------------------------------------------------------------------------- 1 | import { injectable, action, state } from 'reactant'; 2 | import { schema } from 'normalizr'; 3 | import { Users } from './users.service'; 4 | import { IComment, IComments, IUsers } from '../model'; 5 | 6 | @injectable() 7 | class Comments { 8 | constructor(private users: Users) {} 9 | 10 | schema = new schema.Entity('comments', { 11 | user: this.users.schema, 12 | }); 13 | 14 | @state 15 | comments: IComments = {}; 16 | 17 | @action 18 | updateComments(comments: IComments) { 19 | this.comments = { 20 | ...this.comments, 21 | ...comments, 22 | }; 23 | } 24 | 25 | addCommentUsers(users: IUsers) { 26 | this.users.updateUsers(users); 27 | } 28 | 29 | @action 30 | modifyComment(comment: IComment) { 31 | this.comments[comment.id] = comment; 32 | } 33 | } 34 | 35 | export { Comments }; 36 | -------------------------------------------------------------------------------- /examples/ts-bookstore/src/modules/index.ts: -------------------------------------------------------------------------------- 1 | export * from './books.service'; 2 | export * from './comments.service'; 3 | export * from './users.service'; 4 | export * from './shoppingCart.service'; 5 | -------------------------------------------------------------------------------- /examples/ts-bookstore/src/modules/shoppingCart.service.ts: -------------------------------------------------------------------------------- 1 | import { injectable, action, state, computed, watch } from 'reactant'; 2 | import { Storage } from 'reactant-storage'; 3 | 4 | interface IListItem { 5 | id: string; 6 | count: number; 7 | } 8 | 9 | type IList = IListItem[]; 10 | 11 | @injectable({ 12 | name: 'shoppingCart', 13 | }) 14 | class ShoppingCart { 15 | constructor(public storage: Storage) { 16 | this.storage.setStorage(this, { 17 | whitelist: ['list'], 18 | }); 19 | 20 | watch( 21 | this, 22 | () => this.bookCount, 23 | () => { 24 | console.log('bookCount:', this.bookCount); 25 | } 26 | ); 27 | } 28 | 29 | @state 30 | list: IList = []; 31 | 32 | @action 33 | addBook(item: IListItem) { 34 | const book = this.list.find(({ id }) => id === item.id); 35 | if (!book) { 36 | this.list.push(item); 37 | } else { 38 | book.count += item.count; 39 | } 40 | } 41 | 42 | @computed 43 | get bookCount() { 44 | return this.list.reduce((acc, item) => acc + item.count, 0); 45 | } 46 | } 47 | 48 | export { ShoppingCart }; 49 | -------------------------------------------------------------------------------- /examples/ts-bookstore/src/modules/users.service.ts: -------------------------------------------------------------------------------- 1 | import { injectable, action, state } from 'reactant'; 2 | import { schema } from 'normalizr'; 3 | import { IUsers } from '../model'; 4 | 5 | @injectable() 6 | class Users { 7 | schema = new schema.Entity('users'); 8 | 9 | @state 10 | users: IUsers = {}; 11 | 12 | @action 13 | updateUsers(users: IUsers) { 14 | this.users = { 15 | ...this.users, 16 | ...users, 17 | }; 18 | } 19 | } 20 | 21 | export { Users }; 22 | -------------------------------------------------------------------------------- /examples/ts-bookstore/src/views/bookList.view.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ViewModule, injectable, useConnector } from 'reactant'; 3 | import { Books } from '../modules'; 4 | import { BookItem } from '../components'; 5 | import { BookView } from './book.view'; 6 | 7 | @injectable() 8 | class BookListView extends ViewModule { 9 | constructor(private books: Books, private bookView: BookView) { 10 | super(); 11 | } 12 | 13 | component() { 14 | const data = useConnector(() => this.books.booksList); 15 | return ( 16 |
    17 | {data.map((book) => ( 18 |
  • 19 | 24 |
  • 25 | ))} 26 |
27 | ); 28 | } 29 | } 30 | 31 | export { BookListView }; 32 | -------------------------------------------------------------------------------- /examples/ts-bookstore/src/views/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './book.view'; 2 | export * from './home.view'; 3 | export * from './bookList.view'; 4 | export * from './shoppingCart.view'; 5 | -------------------------------------------------------------------------------- /examples/ts-bookstore/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "reactant": ["../../node_modules/reactant"], 7 | "reactant-web": ["../../node_modules/reactant-web"], 8 | "reactant-storage": ["../../node_modules/reactant-storage"], 9 | "reactant-router": ["../../node_modules/reactant-router"] 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /examples/ts-counter/README.md: -------------------------------------------------------------------------------- 1 | ## Start Up 2 | 3 | Make sure the root directory is running `yarn install && yarn build`. 4 | 5 | ```bash 6 | cd examples/ts-counter 7 | yarn install 8 | yarn start 9 | ``` 10 | -------------------------------------------------------------------------------- /examples/ts-counter/global.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | 3 | declare global { 4 | declare const __DEV__: boolean; 5 | interface Window { 6 | __REDUX_DEVTOOLS_EXTENSION_COMPOSE__: any; 7 | app: any; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/ts-counter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ts-counter", 3 | "private": true, 4 | "version": "1.0.0", 5 | "description": "A counter example for Reactant", 6 | "main": "index.js", 7 | "scripts": { 8 | "start": "webpack-dev-server", 9 | "build": "webpack" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "copy-webpack-plugin": "^11.0.0", 16 | "node-polyfill-webpack-plugin": "^2.0.1", 17 | "ts-loader": "^9.4.1", 18 | "typescript": "^5.4.5", 19 | "webpack": "^5.74.0", 20 | "webpack-cli": "^4.10.0", 21 | "webpack-dev-server": "^4.11.1" 22 | }, 23 | "dependencies": { 24 | "react": "^16.12.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/ts-counter/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/ts-counter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "reactant": ["../../node_modules/reactant"], 7 | "reactant-web": ["../../node_modules/reactant-web"], 8 | "reactant-storage": ["../../node_modules/reactant-storage"], 9 | "reactant-router": ["../../node_modules/reactant-router"] 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /examples/ts-vite-counter/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /examples/ts-vite-counter/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import reactHooks from 'eslint-plugin-react-hooks' 4 | import reactRefresh from 'eslint-plugin-react-refresh' 5 | import tseslint from 'typescript-eslint' 6 | 7 | export default tseslint.config( 8 | { ignores: ['dist'] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ['**/*.{ts,tsx}'], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | 'react-hooks': reactHooks, 18 | 'react-refresh': reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | 'react-refresh/only-export-components': [ 23 | 'warn', 24 | { allowConstantExport: true }, 25 | ], 26 | }, 27 | }, 28 | ) 29 | -------------------------------------------------------------------------------- /examples/ts-vite-counter/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/ts-vite-counter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ts-vite-counter", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc -b && vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "react": "^17.0.0", 14 | "react-dom": "^17.0.0" 15 | }, 16 | "devDependencies": { 17 | "@babel/plugin-proposal-decorators": "^7.25.9", 18 | "@babel/plugin-transform-class-properties": "^7.25.9", 19 | "@eslint/js": "^9.21.0", 20 | "@types/react": "^17.0.10", 21 | "@types/react-dom": "^17.0.4", 22 | "@vitejs/plugin-react": "^4.3.4", 23 | "babel-plugin-transform-typescript-metadata": "^0.3.2", 24 | "eslint": "^9.21.0", 25 | "eslint-plugin-react-hooks": "^5.1.0", 26 | "eslint-plugin-react-refresh": "^0.4.19", 27 | "globals": "^15.15.0", 28 | "typescript": "~5.7.2", 29 | "typescript-eslint": "^8.24.1", 30 | "vite": "^6.2.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/ts-vite-counter/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /examples/ts-vite-counter/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | import reactLogo from './assets/react.svg' 3 | import viteLogo from '/vite.svg' 4 | import './App.css' 5 | 6 | function App() { 7 | const [count, setCount] = useState(0) 8 | 9 | return ( 10 | <> 11 | 19 |

Vite + React

20 |
21 | 24 |

25 | Edit src/App.tsx and save to test HMR 26 |

27 |
28 |

29 | Click on the Vite and React logos to learn more 30 |

31 | 32 | ) 33 | } 34 | 35 | export default App 36 | -------------------------------------------------------------------------------- /examples/ts-vite-counter/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/ts-vite-counter/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 4 | "target": "ES2020", 5 | "useDefineForClassFields": true, 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "module": "ESNext", 8 | "skipLibCheck": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "bundler", 12 | "allowImportingTsExtensions": true, 13 | "isolatedModules": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | "jsx": "react-jsx", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "noFallthroughCasesInSwitch": true, 23 | "noUncheckedSideEffectImports": true, 24 | "experimentalDecorators": true, 25 | "emitDecoratorMetadata": true 26 | }, 27 | "include": ["src"] 28 | } 29 | -------------------------------------------------------------------------------- /examples/ts-vite-counter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /examples/ts-vite-counter/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2022", 5 | "lib": ["ES2023"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedSideEffectImports": true, 22 | "experimentalDecorators": true, 23 | "emitDecoratorMetadata": true 24 | }, 25 | "include": ["vite.config.ts"] 26 | } 27 | -------------------------------------------------------------------------------- /examples/ts-vite-counter/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | // https://vite.dev/config/ 5 | export default defineConfig({ 6 | plugins: [ 7 | react({ 8 | babel: { 9 | plugins: [ 10 | ['@babel/plugin-proposal-decorators', { version: 'legacy' }], 11 | 'babel-plugin-transform-typescript-metadata', 12 | [ 13 | '@babel/plugin-transform-class-properties', 14 | { 15 | loose: true, 16 | }, 17 | ], 18 | ], 19 | }, 20 | }), 21 | ], 22 | }); 23 | -------------------------------------------------------------------------------- /globals.d.ts: -------------------------------------------------------------------------------- 1 | declare const __DEV__: boolean; 2 | interface Window { 3 | __REDUX_DEVTOOLS_EXTENSION_COMPOSE__: any; 4 | } 5 | 6 | declare namespace NodeJS { 7 | interface Global { 8 | // 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ], 5 | "useWorkspaces": true, 6 | "npmClient": "yarn", 7 | "version": "0.144.0" 8 | } 9 | -------------------------------------------------------------------------------- /packages/reactant-cli/README.md: -------------------------------------------------------------------------------- 1 | # reactant-cli 2 | 3 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 4 | 5 | A command line interface for Reactant 6 | 7 | ## Usage 8 | 9 | * Create a Reactant project: 10 | 11 | ```bash 12 | npx reactant-cli init my-app 13 | ``` 14 | 15 | * Generate a service file: 16 | 17 | ```bash 18 | npx reactant-cli generate service Foo 19 | # or 20 | npx reactant-cli g s FooBarView 21 | ``` 22 | 23 | * Generate a view file: 24 | 25 | ```bash 26 | npx reactant-cli generate view FooBarView 27 | # or 28 | npx reactant-cli g v FooBarView 29 | ``` 30 | 31 | ## Global installation 32 | 33 | We recommend you install `reactant-cli` globally to use it. 34 | 35 | ```bash 36 | npm install -g reactant-cli 37 | ``` 38 | 39 | or you can install `reactant-cli` to your project. 40 | 41 | ```bash 42 | yarn add -D reactant-cli 43 | ``` 44 | 45 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 46 | -------------------------------------------------------------------------------- /packages/reactant-cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactant-cli", 3 | "version": "0.144.0", 4 | "description": "A command line interface for Reactant", 5 | "engines": { 6 | "node": ">=14" 7 | }, 8 | "bin": { 9 | "reactant-cli": "./dist/index.cjs.js", 10 | "reactant": "./dist/index.cjs.js" 11 | }, 12 | "build": [ 13 | "cjs" 14 | ], 15 | "homepage": "https://reactant.js.org/", 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/unadlib/reactant.git", 19 | "directory": "packages/reactant-cli" 20 | }, 21 | "keywords": [ 22 | "Reactant" 23 | ], 24 | "authors": [ 25 | "Michael Lin (https://github.com/unadlib)" 26 | ], 27 | "license": "MIT", 28 | "dependencies": { 29 | "chalk": "3.0.0", 30 | "commander": "^5.1.0", 31 | "envinfo": "^7.7.3", 32 | "fs-extra": "8.1.0", 33 | "installation": "^0.2.18" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/reactant-cli/src/index.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | import { Command } from 'commander'; 3 | import path from 'path'; 4 | import fs from 'fs-extra'; 5 | import { createInitCommand } from './init'; 6 | import { createInfoCommand } from './info'; 7 | import { createGenerateCommand } from './generate'; 8 | 9 | export interface PackageJson { 10 | name?: string; 11 | version?: string; 12 | dependencies?: Record; 13 | } 14 | 15 | const packageJson = fs.readJsonSync(path.resolve(__dirname, '../package.json')); 16 | const command = new Command() as Command; 17 | command.usage('[command] [options]').version(packageJson.version); 18 | 19 | createInitCommand(command, packageJson); 20 | 21 | createGenerateCommand(command); 22 | 23 | createInfoCommand(command, packageJson); 24 | 25 | command.parse(process.argv); 26 | -------------------------------------------------------------------------------- /packages/reactant-cli/templates/service/template.service.js: -------------------------------------------------------------------------------- 1 | import { injectable } from 'reactant'; 2 | 3 | @injectable({ 4 | name: 'templateService', 5 | deps: [], 6 | }) 7 | class TemplateService { 8 | constructor() {} 9 | } 10 | 11 | export { TemplateService }; 12 | -------------------------------------------------------------------------------- /packages/reactant-cli/templates/service/template.service.spec.js: -------------------------------------------------------------------------------- 1 | import { testBed } from 'reactant'; 2 | import { TemplateService } from './template.service'; 3 | 4 | describe('TemplateService', () => { 5 | let module; 6 | 7 | beforeEach(() => { 8 | module = testBed({ 9 | main: TemplateService, 10 | modules: [], 11 | }).instance; 12 | }); 13 | 14 | test('should be created', () => { 15 | expect(module instanceof TemplateService).toBeTruthy(); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/reactant-cli/templates/service/template.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { testBed } from 'reactant'; 2 | import { TemplateService } from './template.service'; 3 | 4 | describe('TemplateService', () => { 5 | let module: TemplateService; 6 | 7 | beforeEach(() => { 8 | module = testBed({ 9 | main: TemplateService, 10 | modules: [], 11 | }).instance; 12 | }); 13 | 14 | test('should be created', () => { 15 | expect(module instanceof TemplateService).toBeTruthy(); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/reactant-cli/templates/service/template.service.ts: -------------------------------------------------------------------------------- 1 | import { injectable } from 'reactant'; 2 | 3 | @injectable({ 4 | name: 'templateService', 5 | }) 6 | class TemplateService { 7 | constructor() {} 8 | } 9 | 10 | export { TemplateService }; 11 | -------------------------------------------------------------------------------- /packages/reactant-cli/templates/view/template.view.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { injectable, ViewModule } from 'reactant'; 3 | 4 | @injectable({ 5 | deps: [], 6 | }) 7 | class TemplateView extends ViewModule { 8 | constructor() { 9 | super(); 10 | } 11 | 12 | component() { 13 | return <>; 14 | } 15 | } 16 | 17 | export { TemplateView }; 18 | -------------------------------------------------------------------------------- /packages/reactant-cli/templates/view/template.view.spec.jsx: -------------------------------------------------------------------------------- 1 | import { testBed } from 'reactant'; 2 | import { TemplateView } from './template.view'; 3 | 4 | describe('TemplateView', () => { 5 | let module; 6 | 7 | beforeEach(() => { 8 | module = testBed({ 9 | main: TemplateView, 10 | modules: [], 11 | }).instance; 12 | }); 13 | 14 | test('should be created', () => { 15 | expect(module instanceof TemplateView).toBeTruthy(); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/reactant-cli/templates/view/template.view.spec.tsx: -------------------------------------------------------------------------------- 1 | import { testBed } from 'reactant'; 2 | import { TemplateView } from './template.view'; 3 | 4 | describe('TemplateView', () => { 5 | let module: TemplateView; 6 | 7 | beforeEach(() => { 8 | module = testBed({ 9 | main: TemplateView, 10 | modules: [], 11 | }).instance; 12 | }); 13 | 14 | test('should be created', () => { 15 | expect(module instanceof TemplateView).toBeTruthy(); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/reactant-cli/templates/view/template.view.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { injectable, ViewModule } from 'reactant'; 3 | 4 | @injectable() 5 | class TemplateView extends ViewModule { 6 | constructor() { 7 | super(); 8 | } 9 | 10 | component() { 11 | return <>; 12 | } 13 | } 14 | 15 | export { TemplateView }; 16 | -------------------------------------------------------------------------------- /packages/reactant-cli/test/index.test.ts: -------------------------------------------------------------------------------- 1 | test('', () => { 2 | // 3 | }); 4 | -------------------------------------------------------------------------------- /packages/reactant-di/README.md: -------------------------------------------------------------------------------- 1 | # reactant-di 2 | 3 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 4 | 5 | A dependency injection lib for Reactant 6 | 7 | ## Usage 8 | 9 | ```bash 10 | npm install reactant-di 11 | # or 12 | yarn add reactant-di 13 | ``` 14 | 15 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 16 | -------------------------------------------------------------------------------- /packages/reactant-di/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /packages/reactant-di/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactant-di", 3 | "version": "0.144.0", 4 | "description": "A dependency injection lib for Reactant", 5 | "main": "dist/index.cjs.js", 6 | "unpkg": "dist/index.umd.js", 7 | "module": "dist/index.esm.js", 8 | "types": "dist/index.d.ts", 9 | "typedoc": { 10 | "entryPoint": "src/index.ts" 11 | }, 12 | "scripts": { 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "keywords": [ 16 | "Reactant", 17 | "DI", 18 | "dependency injection" 19 | ], 20 | "homepage": "https://reactant.js.org/", 21 | "repository": { 22 | "type": "git", 23 | "url": "git+https://github.com/unadlib/reactant.git", 24 | "directory": "packages/reactant-di" 25 | }, 26 | "authors": [ 27 | "Michael Lin (https://github.com/unadlib)" 28 | ], 29 | "license": "MIT", 30 | "dependencies": { 31 | "inversify": "^5.1.1", 32 | "reflect-metadata": "^0.1.13" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/reactant-di/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const METADATA_KEY = { 2 | optional: 'reactant:optional', 3 | provide: 'reactant:provide', 4 | multiple: 'reactant:multiple', 5 | lazy: 'reactant:lazy', 6 | paramtypes: 'design:paramtypes', 7 | inversifyParamtypes: 'inversify:paramtypes', 8 | inversifyTagged: 'inversify:tagged', 9 | } as const; 10 | -------------------------------------------------------------------------------- /packages/reactant-di/src/decorators/index.ts: -------------------------------------------------------------------------------- 1 | export * from './injectable'; 2 | export * from './inject'; 3 | export * from './optional'; 4 | export * from './multiInject'; 5 | export * from './multiOptional'; 6 | export * from './lazy'; 7 | -------------------------------------------------------------------------------- /packages/reactant-di/src/decorators/multiInject.ts: -------------------------------------------------------------------------------- 1 | import { multiInject as multiInjectWithInversify, decorate } from 'inversify'; 2 | import { METADATA_KEY } from '../constants'; 3 | import { ServiceIdentifier } from '../interfaces'; 4 | import { setMetadata } from '../util'; 5 | 6 | export function multiInject(serviceIdentifier: ServiceIdentifier) { 7 | return (target: object, key?: string, index?: number) => { 8 | const paramtypes = Reflect.getMetadata(METADATA_KEY.paramtypes, target); 9 | setMetadata(METADATA_KEY.multiple, paramtypes?.[index!], serviceIdentifier); 10 | decorate( 11 | multiInjectWithInversify(serviceIdentifier) as ClassDecorator, 12 | target, 13 | index 14 | ); 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /packages/reactant-di/src/decorators/multiOptional.ts: -------------------------------------------------------------------------------- 1 | import { optional as optionalWithInversify, decorate } from 'inversify'; 2 | import { multiInject } from './multiInject'; 3 | import { ServiceIdentifier } from '../interfaces'; 4 | import { METADATA_KEY } from '../constants'; 5 | import { setMetadata } from '../util'; 6 | 7 | export function multiOptional(serviceIdentifier: ServiceIdentifier) { 8 | return (target: object, key?: string, index?: number) => { 9 | const paramtypes = Reflect.getMetadata(METADATA_KEY.paramtypes, target); 10 | setMetadata(METADATA_KEY.optional, paramtypes?.[index!], serviceIdentifier); 11 | setMetadata(METADATA_KEY.multiple, paramtypes?.[index!], serviceIdentifier); 12 | decorate(multiInject(serviceIdentifier) as ClassDecorator, target, index); 13 | decorate(optionalWithInversify() as ClassDecorator, target, index); 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /packages/reactant-di/src/forwardRef.ts: -------------------------------------------------------------------------------- 1 | import { LazyServiceIdentifer } from 'inversify'; 2 | import { ServiceIdentifier } from './interfaces'; 3 | 4 | const forwardRef = (callback: () => ServiceIdentifier) => 5 | new LazyServiceIdentifer(callback); 6 | 7 | export { forwardRef }; 8 | -------------------------------------------------------------------------------- /packages/reactant-di/src/index.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | 3 | export { createContainer, bindModules } from './createContainer'; 4 | export { 5 | inject, 6 | optional, 7 | injectable, 8 | multiInject, 9 | multiOptional, 10 | getLazyDecorator, 11 | } from './decorators/index'; // Don't do `export * from './decorators`. 12 | export { Optional } from './optional'; 13 | export { forwardRef } from './forwardRef'; 14 | export { ModuleRef } from './moduleRef'; 15 | export { METADATA_KEY } from './constants'; 16 | export { getMetadata } from './util'; 17 | export * from './interfaces'; 18 | -------------------------------------------------------------------------------- /packages/reactant-di/src/middlewares/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unadlib/reactant/792fd8e29aa214a3e172d279f6ce82960c06ccb0/packages/reactant-di/src/middlewares/index.ts -------------------------------------------------------------------------------- /packages/reactant-di/src/moduleRef.ts: -------------------------------------------------------------------------------- 1 | import { Container } from 'inversify'; 2 | 3 | /** 4 | * > Make sure that `Container` type for getting module. 5 | */ 6 | class ModuleRef extends Container { 7 | // 8 | } 9 | 10 | export { ModuleRef }; 11 | -------------------------------------------------------------------------------- /packages/reactant-di/src/optional.ts: -------------------------------------------------------------------------------- 1 | import { ServiceIdentifier } from './interfaces'; 2 | 3 | const defaultUndefinedValue = Symbol('defaultUndefined'); 4 | 5 | /** 6 | * > NOTE: does not support Changing dependencies without `@inject`. 7 | */ 8 | class Optional { 9 | constructor(public identifier: ServiceIdentifier) {} 10 | 11 | get key() { 12 | return defaultUndefinedValue; 13 | } 14 | } 15 | 16 | export { Optional, defaultUndefinedValue }; 17 | -------------------------------------------------------------------------------- /packages/reactant-di/test/createContainer.test.ts: -------------------------------------------------------------------------------- 1 | import { injectable, createContainer, inject, forwardRef } from '..'; 2 | 3 | test('forwardRef', () => { 4 | @injectable() 5 | class Foo {} 6 | 7 | @injectable() 8 | class FooBar {} 9 | 10 | @injectable() 11 | class Bar { 12 | constructor(@inject(forwardRef(() => Foo)) public foo: Foo) {} 13 | } 14 | 15 | const ServiceIdentifiers = new Map(); 16 | const container = createContainer({ 17 | ServiceIdentifiers, 18 | modules: [ 19 | FooBar, 20 | { provide: 'string', useValue: 'test' }, 21 | { provide: 'number', useValue: 42 }, 22 | { provide: 'symbol', useValue: Symbol('test') }, 23 | { provide: 'null', useValue: null }, 24 | { provide: 'undefined', useValue: undefined }, 25 | ], 26 | }); 27 | const bar = container.get(Bar); 28 | 29 | expect(bar.foo instanceof Foo).toBeTruthy(); 30 | expect(container.isBound(FooBar)).toBeTruthy(); 31 | }); 32 | -------------------------------------------------------------------------------- /packages/reactant-di/test/decorators/__snapshots__/multiInject.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`multiInject Unexpected multi-Inject 1`] = `"Ambiguous match found for serviceIdentifier: Foo"`; 4 | -------------------------------------------------------------------------------- /packages/reactant-di/test/decorators/multiOptional.test.ts: -------------------------------------------------------------------------------- 1 | import { injectable, createContainer, multiOptional } from '../..'; 2 | 3 | test('@multiOptional for identifier', () => { 4 | @injectable() 5 | class Foo { 6 | public get test() { 7 | return 'test'; 8 | } 9 | } 10 | 11 | @injectable() 12 | class Bar { 13 | constructor(@multiOptional('Foo') public foos: Foo[]) {} 14 | 15 | public get length() { 16 | return this.foos.length; 17 | } 18 | } 19 | 20 | let bar = createContainer({ 21 | ServiceIdentifiers: new Map(), 22 | }).get(Bar); 23 | 24 | expect(bar.foos).toEqual([]); 25 | 26 | bar = createContainer({ 27 | ServiceIdentifiers: new Map(), 28 | modules: [ 29 | { provide: 'Foo', useClass: Foo }, 30 | { provide: 'Foo', useValue: 'test' }, 31 | ], 32 | }).get(Bar); 33 | 34 | expect(bar.length).toBe(2); 35 | expect(bar.foos[1]).toBe('test'); 36 | }); 37 | -------------------------------------------------------------------------------- /packages/reactant-last-action/README.md: -------------------------------------------------------------------------------- 1 | # reactant-last-action 2 | 3 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 4 | 5 | A Reactant plugin for staging last action 6 | 7 | ## Usage 8 | 9 | ```bash 10 | npm install reactant-last-action 11 | # or 12 | yarn add reactant-last-action 13 | ``` 14 | 15 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 16 | -------------------------------------------------------------------------------- /packages/reactant-last-action/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /packages/reactant-last-action/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactant-last-action", 3 | "version": "0.144.0", 4 | "description": "A Reactant plugin for staging last action", 5 | "main": "dist/index.cjs.js", 6 | "unpkg": "dist/index.umd.js", 7 | "module": "dist/index.esm.js", 8 | "types": "dist/index.d.ts", 9 | "typedoc": { 10 | "entryPoint": "src/index.ts" 11 | }, 12 | "scripts": { 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "keywords": [ 16 | "Reactant", 17 | "Reactant Last Action" 18 | ], 19 | "homepage": "https://reactant.js.org/", 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/unadlib/reactant.git", 23 | "directory": "packages/reactant-last-action" 24 | }, 25 | "authors": [ 26 | "Michael Lin (https://github.com/unadlib)" 27 | ], 28 | "license": "MIT", 29 | "peerDependencies": { 30 | "reactant-module": "*", 31 | "redux": "^4.1.0" 32 | }, 33 | "devDependencies": { 34 | "reactant-module": "^0.144.0", 35 | "redux": "^4.1.0" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/reactant-last-action/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lastAction'; 2 | -------------------------------------------------------------------------------- /packages/reactant-model/README.md: -------------------------------------------------------------------------------- 1 | # reactant-model 2 | 3 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 4 | 5 | A model lib for Reactant 6 | 7 | ## Usage 8 | 9 | ```bash 10 | npm install reactant-model 11 | # or 12 | yarn add reactant-model 13 | ``` 14 | 15 | ## Example 16 | 17 | ```js 18 | import { model } from 'reactant-model'; 19 | 20 | const counter = model({ 21 | state: { 22 | count: 0, 23 | }, 24 | actions: { 25 | increase: (num) => (state) => { 26 | state.count += num; 27 | }, 28 | } 29 | }); 30 | ``` 31 | 32 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 33 | -------------------------------------------------------------------------------- /packages/reactant-model/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /packages/reactant-model/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactant-model", 3 | "version": "0.144.0", 4 | "description": "A model lib for Reactant", 5 | "main": "dist/index.cjs.js", 6 | "unpkg": "dist/index.umd.js", 7 | "module": "dist/index.esm.js", 8 | "types": "dist/index.d.ts", 9 | "typedoc": { 10 | "entryPoint": "src/index.ts" 11 | }, 12 | "scripts": { 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "keywords": [ 16 | "Reactant", 17 | "Reactant Model" 18 | ], 19 | "homepage": "https://reactant.js.org/", 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/unadlib/reactant.git", 23 | "directory": "packages/reactant-model" 24 | }, 25 | "authors": [ 26 | "Michael Lin (https://github.com/unadlib)" 27 | ], 28 | "license": "MIT", 29 | "peerDependencies": { 30 | "mutative": "^1.2.0", 31 | "reactant-module": "*" 32 | }, 33 | "devDependencies": { 34 | "mutative": "^1.2.0", 35 | "reactant-module": "^0.144.0" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/reactant-model/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './model'; 2 | -------------------------------------------------------------------------------- /packages/reactant-module/README.md: -------------------------------------------------------------------------------- 1 | # reactant-module 2 | 3 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 4 | 5 | A module model for Reactant 6 | 7 | ## Usage 8 | 9 | ```bash 10 | npm install reactant-module 11 | # or 12 | yarn add reactant-module 13 | ``` 14 | 15 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 16 | -------------------------------------------------------------------------------- /packages/reactant-module/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /packages/reactant-module/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactant-module", 3 | "version": "0.144.0", 4 | "description": "A module model for Reactant", 5 | "main": "dist/index.cjs.js", 6 | "unpkg": "dist/index.umd.js", 7 | "module": "dist/index.esm.js", 8 | "types": "dist/index.d.ts", 9 | "typedoc": { 10 | "entryPoint": "src/index.ts" 11 | }, 12 | "homepage": "https://reactant.js.org/", 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/unadlib/reactant.git", 16 | "directory": "packages/reactant-module" 17 | }, 18 | "scripts": { 19 | "test": "echo \"Error: no test specified\" && exit 1" 20 | }, 21 | "keywords": [ 22 | "Reactant", 23 | "Reactant Module" 24 | ], 25 | "authors": [ 26 | "Michael Lin (https://github.com/unadlib)" 27 | ], 28 | "license": "MIT", 29 | "dependencies": { 30 | "mutative": "^1.2.0", 31 | "reactant-di": "^0.144.0", 32 | "redux": "^4.1.0" 33 | }, 34 | "devDependencies": { 35 | "react": "^17.0.2", 36 | "redux-devtools-extension": "^2.13.8" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/reactant-module/src/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './reduxKeys'; 2 | export * from './moduleKeys'; 3 | -------------------------------------------------------------------------------- /packages/reactant-module/src/constants/moduleKeys.ts: -------------------------------------------------------------------------------- 1 | export const containerKey: unique symbol = Symbol('container'); 2 | export const identifierKey: unique symbol = Symbol('identifier'); 3 | export const modulesKey: unique symbol = Symbol('modules'); 4 | export const nameKey: unique symbol = Symbol('name'); 5 | export const initStateKey: unique symbol = Symbol('initState'); 6 | export const dynamicModulesKey: unique symbol = Symbol('dynamicModules'); 7 | -------------------------------------------------------------------------------- /packages/reactant-module/src/constants/reduxKeys.ts: -------------------------------------------------------------------------------- 1 | export const storeKey: unique symbol = Symbol('store'); 2 | export const loaderKey: unique symbol = Symbol('loader'); 3 | export const subscriptionsKey: unique symbol = Symbol('subscriptions'); 4 | export const unsubscriptionsKey: unique symbol = Symbol('unsubscriptions'); 5 | export const stateKey: unique symbol = Symbol('state'); 6 | export const defaultStateKey: unique symbol = Symbol('defaultState'); 7 | export const signalMapKey: unique symbol = Symbol('signalMap'); 8 | export const enablePatchesKey: unique symbol = Symbol('enablePatches'); 9 | export const enableAutoComputedKey: unique symbol = 10 | Symbol('enableAutoComputed'); 11 | export const enableAutoFreezeKey: unique symbol = Symbol('enableAutoFreeze'); 12 | export const strictKey: unique symbol = Symbol('strict'); 13 | export const enableInspectorKey: unique symbol = Symbol('enableInspector'); 14 | export const checkActionKey: unique symbol = Symbol('checkAction'); 15 | export const actionIdentifier = 'REACTANT_ACTION' as const; 16 | -------------------------------------------------------------------------------- /packages/reactant-module/src/core/applyMiddleware.ts: -------------------------------------------------------------------------------- 1 | import { 2 | applyMiddleware as applyMiddlewareWithRedux, 3 | Middleware, 4 | Store, 5 | } from 'redux'; 6 | import { PluginModule } from './plugin'; 7 | import { storeKey } from '../constants'; 8 | 9 | /** 10 | * ## Description 11 | * Apply middlewares for Redux. 12 | * 13 | * ## Example 14 | * 15 | * ```ts 16 | * import logger from 'redux-logger'; 17 | * 18 | * @injectable() 19 | * class Foo {} 20 | * 21 | * const app = createApp({ 22 | * modules: [applyMiddleware(logger)], 23 | * main: Foo, 24 | * render: () => {}, 25 | * }); 26 | * ``` 27 | * 28 | * @param args middlewares for Redux 29 | */ 30 | const applyMiddleware = (...args: Middleware[]) => { 31 | return class extends PluginModule { 32 | readonly [storeKey]?: Store; 33 | 34 | // eslint-disable-next-line prefer-spread 35 | enhancer = applyMiddlewareWithRedux.apply(null, args); 36 | }; 37 | }; 38 | 39 | export { applyMiddleware }; 40 | -------------------------------------------------------------------------------- /packages/reactant-module/src/core/index.ts: -------------------------------------------------------------------------------- 1 | export * from './view'; 2 | export * from './createStore'; 3 | export * from './dispatch'; 4 | export * from './createState'; 5 | export * from './plugin'; 6 | export * from './handlePlugin'; 7 | export * from './subscribe'; 8 | export * from './watch'; 9 | export * from './load'; 10 | export * from './applyMiddleware'; 11 | export * from './getRef'; 12 | export { untracked, Signal, signal } from './signal'; 13 | -------------------------------------------------------------------------------- /packages/reactant-module/src/core/load.ts: -------------------------------------------------------------------------------- 1 | import { Load } from '../interfaces'; 2 | import { loaderKey } from '../constants'; 3 | import { subscribe } from './subscribe'; 4 | 5 | const load: Load = (service, options) => { 6 | return new Promise((resolve) => { 7 | if (!service[loaderKey]) { 8 | const unsubscribe = subscribe(service, () => { 9 | if (service[loaderKey]) { 10 | unsubscribe(); 11 | service[loaderKey](options, resolve); 12 | } 13 | }); 14 | return; 15 | } 16 | service[loaderKey](options, resolve); 17 | }); 18 | }; 19 | 20 | export { load }; 21 | -------------------------------------------------------------------------------- /packages/reactant-module/src/core/view.ts: -------------------------------------------------------------------------------- 1 | import { Store } from 'redux'; 2 | import { injectable } from 'reactant-di'; 3 | import { identifierKey, storeKey } from '../constants'; 4 | import { Service } from '../interfaces'; 5 | 6 | @injectable() 7 | abstract class ViewModule implements Service { 8 | readonly [identifierKey]?: string; 9 | 10 | readonly [storeKey]?: Store; 11 | 12 | constructor() { 13 | // It needs to ensure that the default props of the component in the current instance can be assigned values, 14 | // and have the correct 'this' binding. 15 | if (typeof this.component !== 'function') { 16 | throw new Error( 17 | `'${ 18 | Object.getPrototypeOf(this).constructor.name 19 | }' ViewModule 'component' property should be defined class 'method'.` 20 | ); 21 | } 22 | this.component = this.component.bind(this); 23 | } 24 | 25 | /** 26 | * React function component defined by the current ViewModule 27 | */ 28 | abstract component(props: Record): React.ReactElement | null; 29 | } 30 | 31 | export { ViewModule }; 32 | -------------------------------------------------------------------------------- /packages/reactant-module/src/decorators/index.ts: -------------------------------------------------------------------------------- 1 | export * from './action'; 2 | export * from './autobind'; 3 | export * from './state'; 4 | export * from './computed'; 5 | export * from './lazy'; 6 | export * from './dynamic'; 7 | export * from './injectable'; 8 | -------------------------------------------------------------------------------- /packages/reactant-module/src/decorators/lazy.ts: -------------------------------------------------------------------------------- 1 | import { getLazyDecorator, ServiceIdentifier } from 'reactant-di'; 2 | 3 | import { containerKey, storeKey } from '../constants'; 4 | import { PropertyDescriptor, Service } from '../interfaces'; 5 | 6 | type Lazy = ( 7 | serviceIdentifier: ServiceIdentifier, 8 | enableCache?: boolean 9 | ) => ( 10 | target: object, 11 | key: string | symbol, 12 | descriptor?: PropertyDescriptor 13 | ) => void; 14 | 15 | export const lazy: Lazy = getLazyDecorator( 16 | (serviceIdentifier, target?: Service) => { 17 | try { 18 | const services = target![containerKey]!.getAll(serviceIdentifier); 19 | return services.length === 1 ? services[0] : services; 20 | } catch (e) { 21 | if (__DEV__ && target?.[storeKey]) { 22 | console.warn( 23 | `Failed to get instance of lazy loading module ${serviceIdentifier.toString()}.` 24 | ); 25 | } 26 | } 27 | return null; 28 | } 29 | ); 30 | -------------------------------------------------------------------------------- /packages/reactant-module/src/index.ts: -------------------------------------------------------------------------------- 1 | export { apply as applyPatches, current, original, unsafe } from 'mutative'; 2 | 3 | export { 4 | inject, 5 | optional, 6 | multiInject, 7 | multiOptional, 8 | getLazyDecorator, 9 | createContainer, 10 | bindModules, 11 | Optional, 12 | forwardRef, 13 | ModuleRef, 14 | getMetadata, 15 | METADATA_KEY, 16 | } from 'reactant-di'; 17 | 18 | export type { 19 | Container, 20 | ValueProvider, 21 | ModuleProvider, 22 | ClassProvider, 23 | FactoryProvider, 24 | ModuleOptions, 25 | ServiceIdentifiersMap, 26 | ContainerOptions, 27 | ServiceIdentifier, 28 | } from 'reactant-di'; 29 | 30 | export * from './core/index'; 31 | export * from './decorators/index'; 32 | export * from './utils/index'; 33 | export * from './constants/index'; 34 | export * from './interfaces'; 35 | -------------------------------------------------------------------------------- /packages/reactant-module/src/utils/assign.ts: -------------------------------------------------------------------------------- 1 | export function assign( 2 | target: object, 3 | key: string | symbol, 4 | value: any, 5 | options?: object 6 | ) { 7 | Object.defineProperty(target, key, { 8 | configurable: true, 9 | writable: true, 10 | enumerable: true, 11 | value, 12 | ...options, 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /packages/reactant-module/src/utils/compose.ts: -------------------------------------------------------------------------------- 1 | import { compose as composeWithReact } from 'redux'; 2 | 3 | export const compose = composeWithReact; 4 | -------------------------------------------------------------------------------- /packages/reactant-module/src/utils/getStageName.ts: -------------------------------------------------------------------------------- 1 | export const getStageName = (className: string) => 2 | `@@reactant/${className}/${Math.random().toString(36)}`; 3 | -------------------------------------------------------------------------------- /packages/reactant-module/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './assign'; 2 | export * from './isEqual'; 3 | export * from './getStageName'; 4 | export * from './performer'; 5 | export * from './reduxDevToolsCompose'; 6 | export * from './compose'; 7 | export * from './selector'; 8 | -------------------------------------------------------------------------------- /packages/reactant-module/src/utils/performer.ts: -------------------------------------------------------------------------------- 1 | export const perform = (funs: Function[], parameter?: any) => 2 | funs.reduce((param: any, fun) => fun(param), parameter); 3 | -------------------------------------------------------------------------------- /packages/reactant-module/src/utils/reduxDevToolsCompose.ts: -------------------------------------------------------------------------------- 1 | import { compose } from 'redux'; 2 | import { ReduxDevToolsOptions } from '../interfaces'; 3 | import { actionIdentifier } from '../constants'; 4 | 5 | export const getComposeEnhancers = ( 6 | enableReduxDevTools: boolean, 7 | reduxDevToolsOptions?: ReduxDevToolsOptions 8 | ) => { 9 | try { 10 | const reduxDevToolsCompose = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__; 11 | return typeof reduxDevToolsCompose === 'function' && enableReduxDevTools 12 | ? reduxDevToolsCompose({ 13 | serialize: true, 14 | actionSanitizer: (action: any) => 15 | action._reactant === actionIdentifier 16 | ? { 17 | ...action, 18 | type: `@@reactant/${action.type}/${action.method}`, 19 | } 20 | : action, 21 | ...reduxDevToolsOptions, 22 | }) 23 | : compose; 24 | } catch (e) { 25 | return compose; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /packages/reactant-module/test/__snapshots__/index.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Unexpected multi-inject: module with multiple module injection with same module or others 1`] = ` 4 | "Ambiguous match found for serviceIdentifier: FooIdentifier 5 | Registered bindings: 6 | Foo 7 | Foo 8 | FooTest" 9 | `; 10 | -------------------------------------------------------------------------------- /packages/reactant-native/README.md: -------------------------------------------------------------------------------- 1 | # reactant-native 2 | 3 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 4 | 5 | A mobile application with react-native for Reactant 6 | 7 | ## Usage 8 | 9 | ```bash 10 | npm install reactant-native 11 | # or 12 | yarn add reactant-native 13 | ``` 14 | 15 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 16 | -------------------------------------------------------------------------------- /packages/reactant-native/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /packages/reactant-native/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './render'; 2 | -------------------------------------------------------------------------------- /packages/reactant-native/src/render.ts: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native'; 2 | 3 | const render = (app: JSX.Element, appName: string) => { 4 | AppRegistry.registerComponent(appName, () => () => app); 5 | }; 6 | 7 | export { render }; 8 | -------------------------------------------------------------------------------- /packages/reactant-native/test/index.test.ts: -------------------------------------------------------------------------------- 1 | test('', () => { 2 | // 3 | }); 4 | -------------------------------------------------------------------------------- /packages/reactant-redux/README.md: -------------------------------------------------------------------------------- 1 | # reactant-redux 2 | 3 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 4 | 5 | A redux lib for Reactant 6 | 7 | ## Usage 8 | 9 | ```bash 10 | npm install reactant-redux 11 | # or 12 | yarn add reactant-redux 13 | ``` 14 | 15 | ## Example 16 | 17 | ```js 18 | import { redux } from 'reactant-redux'; 19 | 20 | const counter = redux({ 21 | reducers: { 22 | count: (state = 0, { type, payload }) => 23 | type === 'increase' ? state + payload : state, 24 | }, 25 | actions: { 26 | increase: num => dispatch => 27 | dispatch({ 28 | type: 'increase', 29 | payload: num, 30 | }), 31 | }, 32 | }); 33 | ``` 34 | 35 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 36 | -------------------------------------------------------------------------------- /packages/reactant-redux/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /packages/reactant-redux/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactant-redux", 3 | "version": "0.144.0", 4 | "description": "A redux lib for Reactant", 5 | "main": "dist/index.cjs.js", 6 | "unpkg": "dist/index.umd.js", 7 | "module": "dist/index.esm.js", 8 | "types": "dist/index.d.ts", 9 | "typedoc": { 10 | "entryPoint": "src/index.ts" 11 | }, 12 | "scripts": { 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "keywords": [ 16 | "Reactant", 17 | "Redux" 18 | ], 19 | "homepage": "https://reactant.js.org/", 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/unadlib/reactant.git", 23 | "directory": "packages/reactant-redux" 24 | }, 25 | "authors": [ 26 | "Michael Lin (https://github.com/unadlib)" 27 | ], 28 | "license": "MIT", 29 | "peerDependencies": { 30 | "reactant-module": "*", 31 | "redux": "^4.1.0" 32 | }, 33 | "devDependencies": { 34 | "reactant-module": "^0.144.0", 35 | "redux": "^4.1.0" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/reactant-redux/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './redux'; 2 | -------------------------------------------------------------------------------- /packages/reactant-router-dom/README.md: -------------------------------------------------------------------------------- 1 | # reactant-router-dom 2 | 3 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 4 | 5 | A react router dom for Reactant 6 | 7 | ## Usage 8 | 9 | ```bash 10 | npm install reactant-router-dom 11 | # or 12 | yarn add reactant-router-dom 13 | ``` 14 | 15 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 16 | -------------------------------------------------------------------------------- /packages/reactant-router-dom/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /packages/reactant-router-dom/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactant-router-dom", 3 | "version": "0.144.0", 4 | "description": "A react router dom for Reactant", 5 | "main": "dist/index.cjs.js", 6 | "unpkg": "dist/index.umd.js", 7 | "module": "dist/index.esm.js", 8 | "types": "dist/index.d.ts", 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "keywords": [ 13 | "Reactant", 14 | "Router", 15 | "History", 16 | "Link", 17 | "React" 18 | ], 19 | "homepage": "https://reactant.js.org/", 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/unadlib/reactant.git", 23 | "directory": "packages/reactant-router-dom" 24 | }, 25 | "authors": [ 26 | "Michael Lin (https://github.com/unadlib)" 27 | ], 28 | "license": "MIT", 29 | "dependencies": { 30 | "@types/react-router-dom": "^5.3.3", 31 | "react-router": "^5.3.1", 32 | "react-router-dom": "^5.3.1" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/reactant-router-dom/src/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | BrowserRouter, 3 | MemoryRouter, 4 | Switch, 5 | Route, 6 | Link, 7 | NavLink, 8 | useRouteMatch, 9 | useParams, 10 | useHistory, 11 | useLocation, 12 | generatePath, 13 | Prompt, 14 | Redirect, 15 | Router, 16 | StaticRouter, 17 | matchPath, 18 | withRouter, 19 | } from 'react-router-dom'; 20 | 21 | export type { 22 | RedirectProps, 23 | RouteChildrenProps, 24 | RouteComponentProps, 25 | SwitchProps, 26 | match, 27 | RouterChildContext, 28 | RouteProps, 29 | } from 'react-router-dom'; 30 | -------------------------------------------------------------------------------- /packages/reactant-router-native/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactant-router-native", 3 | "private": true, 4 | "version": "0.144.0", 5 | "description": "A native apps router with react-native for Reactant", 6 | "main": "dist/index.cjs.js", 7 | "unpkg": "dist/index.umd.js", 8 | "module": "dist/index.esm.js", 9 | "types": "dist/index.d.ts", 10 | "scripts": { 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "keywords": [], 14 | "homepage": "https://reactant.js.org/", 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/unadlib/reactant.git", 18 | "directory": "packages/reactant-router-native" 19 | }, 20 | "authors": [ 21 | "Michael Lin (https://github.com/unadlib)" 22 | ], 23 | "license": "MIT" 24 | } 25 | -------------------------------------------------------------------------------- /packages/reactant-router/README.md: -------------------------------------------------------------------------------- 1 | # reactant-router 2 | 3 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 4 | 5 | A router plugin for Reactant 6 | 7 | ## Usage 8 | 9 | ```bash 10 | npm install reactant-router 11 | # or 12 | yarn add reactant-router 13 | ``` 14 | 15 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 16 | -------------------------------------------------------------------------------- /packages/reactant-router/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /packages/reactant-router/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './router'; 2 | -------------------------------------------------------------------------------- /packages/reactant-share/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /packages/reactant-share/src/createTransport.ts: -------------------------------------------------------------------------------- 1 | import { BroadcastChannel } from 'broadcast-channel'; 2 | import { 3 | createTransport, 4 | Transport, 5 | type TransportOptions, 6 | } from 'data-transport'; 7 | 8 | export const createBroadcastTransport = ( 9 | name: string, 10 | verbose?: boolean, 11 | logger?: TransportOptions['logger'] 12 | ) => { 13 | const broadcastChannel = new BroadcastChannel( 14 | `reactant-share-channel:${name}` 15 | ); 16 | const transport = createTransport('Base', { 17 | listener: (callback) => { 18 | broadcastChannel.onmessage = (data) => { 19 | callback(JSON.parse(data)); 20 | }; 21 | return () => { 22 | broadcastChannel.onmessage = null; 23 | return broadcastChannel.close(); 24 | }; 25 | }, 26 | sender: (message) => broadcastChannel.postMessage(JSON.stringify(message)), 27 | prefix: `reactant-share:${name}`, 28 | verbose, 29 | logger, 30 | }); 31 | return transport; 32 | }; 33 | 34 | export { Transport }; 35 | -------------------------------------------------------------------------------- /packages/reactant-share/src/mockPairTransports.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createTransport, 3 | mockPorts, 4 | type TransportOptions, 5 | } from 'data-transport'; 6 | 7 | /** 8 | * mock pair transports 9 | */ 10 | export const mockPairTransports = (options?: { 11 | serverLogger?: TransportOptions['logger']; 12 | serverVerbose?: boolean; 13 | clientLogger?: TransportOptions['logger']; 14 | clientVerbose?: boolean; 15 | }) => { 16 | const { create, main } = mockPorts(); 17 | return [ 18 | createTransport('Base', { 19 | ...main, 20 | logger: options?.serverLogger, 21 | verbose: options?.serverVerbose, 22 | }), 23 | createTransport('Base', { 24 | ...create(), 25 | logger: options?.clientLogger, 26 | verbose: options?.clientVerbose, 27 | }), 28 | ]; 29 | }; 30 | -------------------------------------------------------------------------------- /packages/reactant-share/src/modules/identifierChecker.ts: -------------------------------------------------------------------------------- 1 | import { PluginModule, injectable } from 'reactant'; 2 | import type { ReducersMapObject } from 'redux'; 3 | 4 | @injectable() 5 | export class IdentifierChecker extends PluginModule { 6 | beforeCombineRootReducers = (reducers: ReducersMapObject) => { 7 | Object.keys(reducers).forEach((key) => { 8 | const [prefix, className] = key.split('/'); 9 | if (prefix === '@@reactant') { 10 | console.error( 11 | `The decorator for class ${className} should set "@injectable({ name: '${className}' })".` 12 | ); 13 | } 14 | }); 15 | return reducers; 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /packages/reactant-share/src/utils.ts: -------------------------------------------------------------------------------- 1 | export const createId = () => Math.random().toString(36).slice(2); 2 | 3 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 4 | // @ts-ignore 5 | export const isSharedWorker = !!globalThis.SharedWorkerGlobalScope; 6 | -------------------------------------------------------------------------------- /packages/reactant-share/test/MemoryStorage.ts: -------------------------------------------------------------------------------- 1 | export class MemoryStorage { 2 | constructor(public data: Record = {}) {} 3 | 4 | getItem(key: string): Promise { 5 | return new Promise((resolve) => { 6 | resolve(this.data[key]); 7 | }); 8 | } 9 | 10 | setItem(key: string, item: string) { 11 | return new Promise((resolve) => { 12 | this.data[key] = item; 13 | resolve(undefined); 14 | }); 15 | } 16 | 17 | removeItem(key: string) { 18 | return new Promise((resolve) => { 19 | delete this.data[key]; 20 | resolve(undefined); 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/reactant-share/test/createApp.test.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { jsdocTests } from 'jsdoc-tests'; 3 | 4 | test('base "createApp" function', async () => { 5 | await jsdocTests('../src/createApp.ts', __dirname); 6 | }); 7 | -------------------------------------------------------------------------------- /packages/reactant-share/workflow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unadlib/reactant/792fd8e29aa214a3e172d279f6ce82960c06ccb0/packages/reactant-share/workflow.jpg -------------------------------------------------------------------------------- /packages/reactant-ssr/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /packages/reactant-ssr/src/appView.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import type { AppProps } from 'next/app'; 3 | import { ViewModule } from 'reactant'; 4 | 5 | /** 6 | * AppView for SSR entry point 7 | */ 8 | export class AppView extends ViewModule { 9 | component({ Component, pageProps }: AppProps) { 10 | return ; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/reactant-ssr/src/createServerApp.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import type { FunctionComponent } from 'react'; 3 | import { AppProps } from 'next/app'; 4 | import { createApp as createBaseApp } from 'reactant'; 5 | import type { Config, Renderer } from 'reactant'; 6 | import { AppView } from './appView'; 7 | import type { ServerConfig, ServerApp } from './interfaces'; 8 | 9 | /** 10 | * create a ServerApp for SSR 11 | */ 12 | export const createServerApp = >( 13 | options: ServerConfig 14 | ): ServerApp => { 15 | const { bootstrap, ...rest } = createBaseApp({ 16 | ...options, 17 | main: options.main ?? (AppView as Config['main']), 18 | render: (element) => element, 19 | }); 20 | const AppComponent = (appProps: AppProps) => { 21 | return (bootstrap as (Component: FunctionComponent) => JSX.Element)( 22 | (Component: FunctionComponent) => 23 | ) as JSX.Element; 24 | }; 25 | return { 26 | bootstrap: AppComponent, 27 | ...rest, 28 | }; 29 | }; 30 | -------------------------------------------------------------------------------- /packages/reactant-ssr/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from 'reactant'; 2 | 3 | export * from './createServerApp'; 4 | export * from './appView'; 5 | -------------------------------------------------------------------------------- /packages/reactant-ssr/src/interfaces.ts: -------------------------------------------------------------------------------- 1 | import { AppProps } from 'next/app'; 2 | import { FunctionComponent } from 'react'; 3 | import { App, Config, Renderer } from 'reactant'; 4 | 5 | export interface ServerConfig> 6 | extends Pick< 7 | Config, 8 | Exclude, 'render' | 'main'> 9 | > { 10 | main?: Config['main']; 11 | } 12 | 13 | export interface ServerApp> 14 | extends Pick, Exclude, 'bootstrap'>> { 15 | bootstrap: FunctionComponent; 16 | } 17 | -------------------------------------------------------------------------------- /packages/reactant-storage/README.md: -------------------------------------------------------------------------------- 1 | # reactant-storage 2 | 3 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 4 | 5 | A persistence storage plugin for Reactant 6 | 7 | ## Usage 8 | 9 | ```bash 10 | npm install reactant-storage 11 | # or 12 | yarn add reactant-storage 13 | ``` 14 | 15 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 16 | -------------------------------------------------------------------------------- /packages/reactant-storage/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /packages/reactant-storage/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './storage'; 2 | -------------------------------------------------------------------------------- /packages/reactant-template/README.md: -------------------------------------------------------------------------------- 1 | # reactant-storage 2 | 3 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 4 | 5 | A templates collection for Reactant 6 | 7 | ## Usage 8 | 9 | ```bash 10 | npm install -D reactant-template 11 | # or 12 | yarn add -D reactant-template 13 | ``` 14 | 15 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 16 | -------------------------------------------------------------------------------- /packages/reactant-template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactant-template", 3 | "version": "0.144.0", 4 | "description": "A templates collection for Reactant", 5 | "main": "index.js", 6 | "build": [], 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "keywords": [ 11 | "Reactant" 12 | ], 13 | "homepage": "https://reactant.js.org/", 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/unadlib/reactant.git", 17 | "directory": "packages/reactant-template" 18 | }, 19 | "authors": [ 20 | "Michael Lin (https://github.com/unadlib)" 21 | ], 22 | "license": "MIT" 23 | } 24 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/javascript/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "start": "webpack-cli serve --open", 4 | "build": "webpack", 5 | "test": "jest --config jest.json" 6 | }, 7 | "devDependencies": { 8 | "@babel/core": "^7.15.5", 9 | "@babel/plugin-proposal-class-properties": "^7.14.5", 10 | "@babel/plugin-proposal-decorators": "^7.15.4", 11 | "@babel/preset-env": "^7.15.6", 12 | "@babel/preset-react": "^7.14.5", 13 | "babel-loader": "^8.2.2", 14 | "copy-webpack-plugin": "^9.0.1", 15 | "jest": "^27.2.4", 16 | "serve": "^12.0.1", 17 | "webpack": "^5.56.0", 18 | "webpack-cli": "^4.8.0", 19 | "webpack-dev-server": "^4.3.0" 20 | }, 21 | "dependencies": { 22 | "react": "*", 23 | "react-dom": "*", 24 | "reactant": "*", 25 | "reactant-share": "*", 26 | "reactant-web": "*" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/javascript/template/README.md: -------------------------------------------------------------------------------- 1 | This project was created with [Reactant CLI](https://github.com/unadlib/reactant/tree/master/packages/reactant-cli). 2 | 3 | ### Development 4 | 5 | ```bash 6 | yarn start 7 | ``` 8 | 9 | Runs the app in the development mode, and open [http://localhost:7000](http://localhost:7000) to view it in the browser. 10 | 11 | ### Build 12 | 13 | ```bash 14 | yarn build 15 | ``` 16 | 17 | Build the project, and build files are stored in the `dist/` directory. Use the `--mode=production` flag for a production build. 18 | 19 | ### Test 20 | 21 | ```bash 22 | yarn test 23 | ``` 24 | 25 | Running unit tests via [jest](https://jestjs.io). 26 | 27 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/javascript/template/babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "loose": true 7 | } 8 | ], 9 | "@babel/preset-react" 10 | ], 11 | "plugins": [ 12 | [ 13 | "@babel/plugin-proposal-decorators", 14 | { 15 | "legacy": true 16 | } 17 | ], 18 | [ 19 | "@babel/plugin-proposal-class-properties", 20 | { 21 | "loose": true 22 | } 23 | ] 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/javascript/template/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/reactant-template/templates/shared-tab/javascript/template/jest.json: -------------------------------------------------------------------------------- 1 | { 2 | "transform": { 3 | "^.+\\.[t|j]sx?$": "babel-jest" 4 | }, 5 | "testEnvironment": "jsdom" 6 | } 7 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/javascript/template/src/app.view.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ViewModule, injectable, useConnector, delegate } from 'reactant-share'; 3 | import { CounterService } from './counter.service'; 4 | 5 | @injectable({ 6 | deps: [CounterService], 7 | }) 8 | class AppView extends ViewModule { 9 | constructor(counter) { 10 | super(); 11 | this.counter = counter; 12 | } 13 | 14 | component() { 15 | const count = useConnector(() => this.counter.count); 16 | return ( 17 | <> 18 | 24 |
{count}
25 | 31 | 32 | ); 33 | } 34 | } 35 | 36 | export { AppView }; 37 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/javascript/template/src/counter.service.js: -------------------------------------------------------------------------------- 1 | import { injectable, action, state } from 'reactant-share'; 2 | 3 | @injectable({ 4 | name: 'counter', 5 | }) 6 | class CounterService { 7 | @state 8 | count = 0; 9 | 10 | @action 11 | increase() { 12 | this.count += 1; 13 | } 14 | 15 | @action 16 | decrease() { 17 | this.count -= 1; 18 | } 19 | } 20 | 21 | export { CounterService }; 22 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/javascript/template/src/counter.service.spec.js: -------------------------------------------------------------------------------- 1 | import { testBed } from 'reactant-share'; 2 | import { CounterService } from './counter.service'; 3 | 4 | describe('CounterService', () => { 5 | let module; 6 | 7 | beforeEach(() => { 8 | module = testBed({ 9 | main: CounterService, 10 | modules: [], 11 | }).instance; 12 | }); 13 | 14 | test('should be created', () => { 15 | expect(module instanceof CounterService).toBeTruthy(); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/javascript/template/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/javascript/template/src/index.js: -------------------------------------------------------------------------------- 1 | import { render } from 'reactant-web'; 2 | import { createSharedApp } from 'reactant-share'; 3 | import { AppView } from './app.view'; 4 | 5 | createSharedApp({ 6 | modules: [], 7 | main: AppView, 8 | render, 9 | share: { 10 | name: 'SharedApp', 11 | type: 'SharedTab', 12 | }, 13 | }).then((app) => { 14 | app.bootstrap(document.getElementById('app')); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/javascript/template/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-var-requires */ 2 | const path = require('path'); 3 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 4 | 5 | module.exports = { 6 | entry: './src/index.js', 7 | output: { 8 | path: path.resolve(__dirname, 'dist'), 9 | filename: 'bundle.js', 10 | }, 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.m?jsx?$/, 15 | exclude: /node_modules/, 16 | use: { 17 | loader: 'babel-loader', 18 | }, 19 | }, 20 | ], 21 | }, 22 | resolve: { 23 | extensions: ['.jsx', '.js'], 24 | }, 25 | mode: 'development', 26 | devServer: { 27 | static: { 28 | directory: path.join(__dirname, 'public'), 29 | }, 30 | compress: true, 31 | port: 7001, 32 | }, 33 | plugins: [ 34 | new CopyWebpackPlugin({ 35 | patterns: [path.join(__dirname, './src/index.html')], 36 | }), 37 | ], 38 | }; 39 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/typescript/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "start": "webpack-cli serve --open", 4 | "build": "webpack", 5 | "test": "jest --config jest.json" 6 | }, 7 | "devDependencies": { 8 | "@types/jest": "^27.0.2", 9 | "@types/node": "^16.10.2", 10 | "@types/react": "^17.0.14", 11 | "@types/react-dom": "^17.0.9", 12 | "@types/react-redux": "^7.1.18", 13 | "@types/react-router-dom": "^5.1.8", 14 | "copy-webpack-plugin": "^9.0.1", 15 | "jest": "^27.2.4", 16 | "serve": "^12.0.1", 17 | "ts-jest": "^27.0.5", 18 | "ts-loader": "^9.2.6", 19 | "tslib": "^2.3.1", 20 | "typescript": "^5.4.5", 21 | "webpack": "^5.56.0", 22 | "webpack-cli": "^4.8.0", 23 | "webpack-dev-server": "^4.3.0" 24 | }, 25 | "dependencies": { 26 | "react": "*", 27 | "react-dom": "*", 28 | "reactant": "*", 29 | "reactant-share": "*", 30 | "reactant-web": "*" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/typescript/template/README.md: -------------------------------------------------------------------------------- 1 | This project was created with [Reactant CLI](https://github.com/unadlib/reactant/tree/master/packages/reactant-cli). 2 | 3 | ### Development 4 | 5 | ```bash 6 | yarn start 7 | ``` 8 | 9 | Runs the app in the development mode, and open [http://localhost:7000](http://localhost:7000) to view it in the browser. 10 | 11 | ### Build 12 | 13 | ```bash 14 | yarn build 15 | ``` 16 | 17 | Build the project, and build files are stored in the `dist/` directory. Use the `--mode=production` flag for a production build. 18 | 19 | ### Test 20 | 21 | ```bash 22 | yarn test 23 | ``` 24 | 25 | Running unit tests via [jest](https://jestjs.io). 26 | 27 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/typescript/template/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/reactant-template/templates/shared-tab/typescript/template/jest.json: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "ts-jest", 3 | "testEnvironment": "jsdom" 4 | } 5 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/typescript/template/src/app.view.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ViewModule, injectable, useConnector, delegate } from 'reactant-share'; 3 | import { CounterService } from './counter.service'; 4 | 5 | @injectable() 6 | class AppView extends ViewModule { 7 | constructor(public counter: CounterService) { 8 | super(); 9 | } 10 | 11 | component() { 12 | const count = useConnector(() => this.counter.count); 13 | return ( 14 | <> 15 | 21 |
{count}
22 | 28 | 29 | ); 30 | } 31 | } 32 | 33 | export { AppView }; 34 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/typescript/template/src/counter.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { testBed } from 'reactant-share'; 2 | import { CounterService } from './counter.service'; 3 | 4 | describe('CounterService', () => { 5 | let module: CounterService; 6 | 7 | beforeEach(() => { 8 | module = testBed({ 9 | main: CounterService, 10 | modules: [], 11 | }).instance; 12 | }); 13 | 14 | test('should be created', () => { 15 | expect(module instanceof CounterService).toBeTruthy(); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/typescript/template/src/counter.service.ts: -------------------------------------------------------------------------------- 1 | import { injectable, action, state } from 'reactant-share'; 2 | 3 | @injectable({ 4 | name: 'counter', 5 | }) 6 | class CounterService { 7 | @state 8 | count = 0; 9 | 10 | @action 11 | increase() { 12 | this.count += 1; 13 | } 14 | 15 | @action 16 | decrease() { 17 | this.count -= 1; 18 | } 19 | } 20 | 21 | export { CounterService }; 22 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/typescript/template/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/typescript/template/src/index.ts: -------------------------------------------------------------------------------- 1 | import { render } from 'reactant-web'; 2 | import { createSharedApp } from 'reactant-share'; 3 | import { AppView } from './app.view'; 4 | 5 | createSharedApp({ 6 | modules: [], 7 | main: AppView, 8 | render, 9 | share: { 10 | name: 'SharedApp', 11 | type: 'SharedTab', 12 | }, 13 | }).then((app) => { 14 | app.bootstrap(document.getElementById('app')); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/typescript/template/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/", 6 | "jsx": "react", 7 | "sourceMap": true, 8 | "declaration": false, 9 | "downlevelIteration": true, 10 | "emitDecoratorMetadata": true, 11 | "experimentalDecorators": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "importHelpers": true, 15 | "target": "es2015", 16 | "typeRoots": [ 17 | "node_modules/@types" 18 | ], 19 | "allowSyntheticDefaultImports": true, 20 | "lib": [ 21 | "es2018", 22 | "dom" 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-tab/typescript/template/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 3 | 4 | module.exports = { 5 | entry: './src/index.ts', 6 | output: { 7 | path: path.resolve(__dirname, 'dist'), 8 | filename: 'bundle.js', 9 | }, 10 | module: { 11 | rules: [ 12 | { 13 | test: /\.tsx?$/, 14 | use: 'ts-loader', 15 | exclude: /node_modules/, 16 | }, 17 | ], 18 | }, 19 | resolve: { 20 | extensions: ['.tsx', '.ts', '.jsx', '.js'], 21 | }, 22 | mode: 'development', 23 | devServer: { 24 | static: { 25 | directory: path.join(__dirname, 'public'), 26 | }, 27 | compress: true, 28 | port: 7001, 29 | }, 30 | plugins: [ 31 | new CopyWebpackPlugin({ 32 | patterns: [path.join(__dirname, './src/index.html')], 33 | }), 34 | ], 35 | }; 36 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/javascript/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "start": "webpack-cli serve --open", 4 | "build": "webpack", 5 | "test": "jest --config jest.json" 6 | }, 7 | "devDependencies": { 8 | "@babel/core": "^7.15.5", 9 | "@babel/plugin-proposal-class-properties": "^7.14.5", 10 | "@babel/plugin-proposal-decorators": "^7.15.4", 11 | "@babel/preset-env": "^7.15.6", 12 | "@babel/preset-react": "^7.14.5", 13 | "babel-loader": "^8.2.2", 14 | "copy-webpack-plugin": "^9.0.1", 15 | "jest": "^27.2.4", 16 | "serve": "^12.0.1", 17 | "webpack": "^5.56.0", 18 | "webpack-cli": "^4.8.0", 19 | "webpack-dev-server": "^4.3.0" 20 | }, 21 | "dependencies": { 22 | "react": "*", 23 | "react-dom": "*", 24 | "reactant": "*", 25 | "reactant-share": "*", 26 | "reactant-web": "*" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/javascript/template/README.md: -------------------------------------------------------------------------------- 1 | This project was created with [Reactant CLI](https://github.com/unadlib/reactant/tree/master/packages/reactant-cli). 2 | 3 | ### Development 4 | 5 | ```bash 6 | yarn start 7 | ``` 8 | 9 | Runs the app in the development mode, and open [http://localhost:7000](http://localhost:7000) to view it in the browser. 10 | 11 | ### Build 12 | 13 | ```bash 14 | yarn build 15 | ``` 16 | 17 | Build the project, and build files are stored in the `dist/` directory. Use the `--mode=production` flag for a production build. 18 | 19 | ### Test 20 | 21 | ```bash 22 | yarn test 23 | ``` 24 | 25 | Running unit tests via [jest](https://jestjs.io). 26 | 27 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/javascript/template/babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "loose": true 7 | } 8 | ], 9 | "@babel/preset-react" 10 | ], 11 | "plugins": [ 12 | [ 13 | "@babel/plugin-proposal-decorators", 14 | { 15 | "legacy": true 16 | } 17 | ], 18 | [ 19 | "@babel/plugin-proposal-class-properties", 20 | { 21 | "loose": true 22 | } 23 | ] 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/javascript/template/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/reactant-template/templates/shared-worker/javascript/template/jest.json: -------------------------------------------------------------------------------- 1 | { 2 | "transform": { 3 | "^.+\\.[t|j]sx?$": "babel-jest" 4 | }, 5 | "testEnvironment": "jsdom" 6 | } 7 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/javascript/template/src/app.view.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ViewModule, injectable, useConnector, delegate } from 'reactant-share'; 3 | import { CounterService } from './counter.service'; 4 | 5 | @injectable({ 6 | deps: [CounterService], 7 | }) 8 | class AppView extends ViewModule { 9 | constructor(counter) { 10 | super(); 11 | this.counter = counter; 12 | } 13 | 14 | component() { 15 | const count = useConnector(() => this.counter.count); 16 | return ( 17 | <> 18 | 24 |
{count}
25 | 31 | 32 | ); 33 | } 34 | } 35 | 36 | export { AppView }; 37 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/javascript/template/src/counter.service.js: -------------------------------------------------------------------------------- 1 | import { injectable, action, state } from 'reactant-share'; 2 | 3 | @injectable({ 4 | name: 'counter', 5 | }) 6 | class CounterService { 7 | @state 8 | count = 0; 9 | 10 | @action 11 | increase() { 12 | this.count += 1; 13 | } 14 | 15 | @action 16 | decrease() { 17 | this.count -= 1; 18 | } 19 | } 20 | 21 | export { CounterService }; 22 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/javascript/template/src/counter.service.spec.js: -------------------------------------------------------------------------------- 1 | import { testBed } from 'reactant-share'; 2 | import { CounterService } from './counter.service'; 3 | 4 | describe('CounterService', () => { 5 | let module; 6 | 7 | beforeEach(() => { 8 | module = testBed({ 9 | main: CounterService, 10 | modules: [], 11 | }).instance; 12 | }); 13 | 14 | test('should be created', () => { 15 | expect(module instanceof CounterService).toBeTruthy(); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/javascript/template/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/javascript/template/src/index.js: -------------------------------------------------------------------------------- 1 | import { render } from 'reactant-web'; 2 | import { createSharedApp } from 'reactant-share'; 3 | import { AppView } from './app.view'; 4 | 5 | createSharedApp({ 6 | modules: [], 7 | main: AppView, 8 | render, 9 | share: { 10 | name: 'SharedWorkerApp', 11 | port: 'client', 12 | type: 'SharedWorker', 13 | workerURL: 'worker.bundle.js', 14 | }, 15 | }).then((app) => { 16 | app.bootstrap(document.getElementById('app')); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/javascript/template/src/worker.js: -------------------------------------------------------------------------------- 1 | import { createSharedApp } from 'reactant-share'; 2 | import { AppView } from './app.view'; 3 | 4 | createSharedApp({ 5 | modules: [], 6 | main: AppView, 7 | render: () => { 8 | // 9 | }, 10 | share: { 11 | name: 'SharedWorkerApp', 12 | port: 'server', 13 | type: 'SharedWorker', 14 | }, 15 | }).then((app) => { 16 | // renderless 17 | }); 18 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/javascript/template/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-var-requires */ 2 | const path = require('path'); 3 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 4 | 5 | module.exports = { 6 | entry: { 7 | index: './src/index.js', 8 | worker: './src/worker.js', 9 | }, 10 | output: { 11 | path: path.resolve(__dirname, 'dist'), 12 | filename: '[name].bundle.js', 13 | }, 14 | module: { 15 | rules: [ 16 | { 17 | test: /\.m?jsx?$/, 18 | exclude: /node_modules/, 19 | use: { 20 | loader: 'babel-loader', 21 | }, 22 | }, 23 | ], 24 | }, 25 | resolve: { 26 | extensions: ['.jsx', '.js'], 27 | }, 28 | mode: 'development', 29 | devServer: { 30 | static: { 31 | directory: path.join(__dirname, 'public'), 32 | }, 33 | compress: true, 34 | port: 7001, 35 | }, 36 | plugins: [ 37 | new CopyWebpackPlugin({ 38 | patterns: [path.join(__dirname, './src/index.html')], 39 | }), 40 | ], 41 | }; 42 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/typescript/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "start": "webpack-cli serve --open", 4 | "build": "webpack", 5 | "test": "jest --config jest.json" 6 | }, 7 | "devDependencies": { 8 | "@types/jest": "^27.0.2", 9 | "@types/node": "^16.10.2", 10 | "@types/react": "^17.0.14", 11 | "@types/react-dom": "^17.0.9", 12 | "@types/react-redux": "^7.1.18", 13 | "@types/react-router-dom": "^5.1.8", 14 | "copy-webpack-plugin": "^9.0.1", 15 | "jest": "^27.2.4", 16 | "serve": "^12.0.1", 17 | "ts-jest": "^27.0.5", 18 | "ts-loader": "^9.2.6", 19 | "tslib": "^2.3.1", 20 | "typescript": "^5.4.5", 21 | "webpack": "^5.56.0", 22 | "webpack-cli": "^4.8.0", 23 | "webpack-dev-server": "^4.3.0" 24 | }, 25 | "dependencies": { 26 | "react": "*", 27 | "react-dom": "*", 28 | "reactant": "*", 29 | "reactant-share": "*", 30 | "reactant-web": "*" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/typescript/template/README.md: -------------------------------------------------------------------------------- 1 | This project was created with [Reactant CLI](https://github.com/unadlib/reactant/tree/master/packages/reactant-cli). 2 | 3 | ### Development 4 | 5 | ```bash 6 | yarn start 7 | ``` 8 | 9 | Runs the app in the development mode, and open [http://localhost:7000](http://localhost:7000) to view it in the browser. 10 | 11 | ### Build 12 | 13 | ```bash 14 | yarn build 15 | ``` 16 | 17 | Build the project, and build files are stored in the `dist/` directory. Use the `--mode=production` flag for a production build. 18 | 19 | ### Test 20 | 21 | ```bash 22 | yarn test 23 | ``` 24 | 25 | Running unit tests via [jest](https://jestjs.io). 26 | 27 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/typescript/template/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/reactant-template/templates/shared-worker/typescript/template/jest.json: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "ts-jest", 3 | "testEnvironment": "jsdom" 4 | } 5 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/typescript/template/src/app.view.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ViewModule, injectable, useConnector, delegate } from 'reactant-share'; 3 | import { CounterService } from './counter.service'; 4 | 5 | @injectable() 6 | class AppView extends ViewModule { 7 | constructor(public counter: CounterService) { 8 | super(); 9 | } 10 | 11 | component() { 12 | const count = useConnector(() => this.counter.count); 13 | return ( 14 | <> 15 | 21 |
{count}
22 | 28 | 29 | ); 30 | } 31 | } 32 | 33 | export { AppView }; 34 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/typescript/template/src/counter.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { testBed } from 'reactant-share'; 2 | import { CounterService } from './counter.service'; 3 | 4 | describe('CounterService', () => { 5 | let module: CounterService; 6 | 7 | beforeEach(() => { 8 | module = testBed({ 9 | main: CounterService, 10 | modules: [], 11 | }).instance; 12 | }); 13 | 14 | test('should be created', () => { 15 | expect(module instanceof CounterService).toBeTruthy(); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/typescript/template/src/counter.service.ts: -------------------------------------------------------------------------------- 1 | import { injectable, action, state } from 'reactant-share'; 2 | 3 | @injectable({ 4 | name: 'counter', 5 | }) 6 | class CounterService { 7 | @state 8 | count = 0; 9 | 10 | @action 11 | increase() { 12 | this.count += 1; 13 | } 14 | 15 | @action 16 | decrease() { 17 | this.count -= 1; 18 | } 19 | } 20 | 21 | export { CounterService }; 22 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/typescript/template/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/typescript/template/src/index.ts: -------------------------------------------------------------------------------- 1 | import { render } from 'reactant-web'; 2 | import { createSharedApp } from 'reactant-share'; 3 | import { AppView } from './app.view'; 4 | 5 | createSharedApp({ 6 | modules: [], 7 | main: AppView, 8 | render, 9 | share: { 10 | name: 'SharedWorkerApp', 11 | port: 'client', 12 | type: 'SharedWorker', 13 | workerURL: 'worker.bundle.js', 14 | }, 15 | }).then((app) => { 16 | app.bootstrap(document.getElementById('app')); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/typescript/template/src/worker.ts: -------------------------------------------------------------------------------- 1 | import { createSharedApp } from 'reactant-share'; 2 | import { AppView } from './app.view'; 3 | 4 | createSharedApp({ 5 | modules: [], 6 | main: AppView, 7 | render: () => { 8 | // 9 | }, 10 | share: { 11 | name: 'SharedWorkerApp', 12 | port: 'server', 13 | type: 'SharedWorker', 14 | }, 15 | }).then((app) => { 16 | // renderless 17 | }); 18 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/typescript/template/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/", 6 | "jsx": "react", 7 | "sourceMap": true, 8 | "declaration": false, 9 | "downlevelIteration": true, 10 | "emitDecoratorMetadata": true, 11 | "experimentalDecorators": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "importHelpers": true, 15 | "target": "es2015", 16 | "typeRoots": [ 17 | "node_modules/@types" 18 | ], 19 | "allowSyntheticDefaultImports": true, 20 | "lib": [ 21 | "es2018", 22 | "dom" 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/shared-worker/typescript/template/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 3 | 4 | module.exports = { 5 | entry: { 6 | index: './src/index.ts', 7 | worker: './src/worker.ts', 8 | }, 9 | output: { 10 | path: path.resolve(__dirname, 'dist'), 11 | filename: '[name].bundle.js', 12 | }, 13 | module: { 14 | rules: [ 15 | { 16 | test: /\.tsx?$/, 17 | use: 'ts-loader', 18 | exclude: /node_modules/, 19 | }, 20 | ], 21 | }, 22 | resolve: { 23 | extensions: ['.tsx', '.ts', '.jsx', '.js'], 24 | }, 25 | mode: 'development', 26 | devServer: { 27 | static: { 28 | directory: path.join(__dirname, 'public'), 29 | }, 30 | compress: true, 31 | port: 7001, 32 | }, 33 | plugins: [ 34 | new CopyWebpackPlugin({ 35 | patterns: [path.join(__dirname, './src/index.html')], 36 | }), 37 | ], 38 | }; 39 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/javascript/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "start": "webpack-cli serve --open", 4 | "build": "webpack", 5 | "test": "jest --config jest.json" 6 | }, 7 | "devDependencies": { 8 | "@babel/core": "^7.15.5", 9 | "@babel/plugin-proposal-class-properties": "^7.14.5", 10 | "@babel/plugin-proposal-decorators": "^7.15.4", 11 | "@babel/preset-env": "^7.15.6", 12 | "@babel/preset-react": "^7.14.5", 13 | "babel-loader": "^8.2.2", 14 | "copy-webpack-plugin": "^9.0.1", 15 | "jest": "^27.2.4", 16 | "serve": "^12.0.1", 17 | "webpack": "^5.56.0", 18 | "webpack-cli": "^4.8.0", 19 | "webpack-dev-server": "^4.3.0" 20 | }, 21 | "dependencies": { 22 | "react": "*", 23 | "react-dom": "*", 24 | "reactant": "*", 25 | "reactant-web": "*" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/javascript/template/README.md: -------------------------------------------------------------------------------- 1 | This project was created with [Reactant CLI](https://github.com/unadlib/reactant/tree/master/packages/reactant-cli). 2 | 3 | ### Development 4 | 5 | ```bash 6 | yarn start 7 | ``` 8 | 9 | Runs the app in the development mode, and open [http://localhost:7000](http://localhost:7000) to view it in the browser. 10 | 11 | ### Build 12 | 13 | ```bash 14 | yarn build 15 | ``` 16 | 17 | Build the project, and build files are stored in the `dist/` directory. Use the `--mode=production` flag for a production build. 18 | 19 | ### Test 20 | 21 | ```bash 22 | yarn test 23 | ``` 24 | 25 | Running unit tests via [jest](https://jestjs.io). 26 | 27 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/javascript/template/babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "loose": true 7 | } 8 | ], 9 | "@babel/preset-react" 10 | ], 11 | "plugins": [ 12 | [ 13 | "@babel/plugin-proposal-decorators", 14 | { 15 | "legacy": true 16 | } 17 | ], 18 | [ 19 | "@babel/plugin-proposal-class-properties", 20 | { 21 | "loose": true 22 | } 23 | ] 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/javascript/template/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/reactant-template/templates/web/javascript/template/jest.json: -------------------------------------------------------------------------------- 1 | { 2 | "transform": { 3 | "^.+\\.[t|j]sx?$": "babel-jest" 4 | }, 5 | "testEnvironment": "jsdom" 6 | } 7 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/javascript/template/src/app.view.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ViewModule, injectable, useConnector } from 'reactant'; 3 | import { CounterService } from './counter.service'; 4 | 5 | @injectable({ 6 | deps: [CounterService], 7 | }) 8 | class AppView extends ViewModule { 9 | constructor(counter) { 10 | super(); 11 | this.counter = counter; 12 | } 13 | 14 | component() { 15 | const count = useConnector(() => this.counter.count); 16 | return ( 17 | <> 18 | 21 |
{count}
22 | 25 | 26 | ); 27 | } 28 | } 29 | 30 | export { AppView }; 31 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/javascript/template/src/counter.service.js: -------------------------------------------------------------------------------- 1 | import { injectable, action, state } from 'reactant'; 2 | 3 | @injectable() 4 | class CounterService { 5 | @state 6 | count = 0; 7 | 8 | @action 9 | increase() { 10 | this.count += 1; 11 | } 12 | 13 | @action 14 | decrease() { 15 | this.count -= 1; 16 | } 17 | } 18 | 19 | export { CounterService }; 20 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/javascript/template/src/counter.service.spec.js: -------------------------------------------------------------------------------- 1 | import { testBed } from 'reactant'; 2 | import { CounterService } from './counter.service'; 3 | 4 | describe('CounterService', () => { 5 | let module; 6 | 7 | beforeEach(() => { 8 | module = testBed({ 9 | main: CounterService, 10 | modules: [], 11 | }).instance; 12 | }); 13 | 14 | test('should be created', () => { 15 | expect(module instanceof CounterService).toBeTruthy(); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/javascript/template/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/javascript/template/src/index.js: -------------------------------------------------------------------------------- 1 | import { render } from 'reactant-web'; 2 | import { createApp } from 'reactant'; 3 | import { AppView } from './app.view'; 4 | 5 | const app = createApp({ 6 | modules: [], 7 | main: AppView, 8 | render, 9 | }); 10 | 11 | app.bootstrap(document.getElementById('app')); 12 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/javascript/template/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-var-requires */ 2 | const path = require('path'); 3 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 4 | 5 | module.exports = { 6 | entry: './src/index.js', 7 | output: { 8 | path: path.resolve(__dirname, 'dist'), 9 | filename: 'bundle.js', 10 | }, 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.m?jsx?$/, 15 | exclude: /node_modules/, 16 | use: { 17 | loader: 'babel-loader', 18 | }, 19 | }, 20 | ], 21 | }, 22 | resolve: { 23 | extensions: ['.jsx', '.js'], 24 | }, 25 | mode: 'development', 26 | devServer: { 27 | static: { 28 | directory: path.join(__dirname, 'public'), 29 | }, 30 | compress: true, 31 | port: 7001, 32 | }, 33 | plugins: [ 34 | new CopyWebpackPlugin({ 35 | patterns: [path.join(__dirname, './src/index.html')], 36 | }), 37 | ], 38 | }; 39 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/typescript/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "start": "webpack-cli serve --open", 4 | "build": "webpack", 5 | "test": "jest --config jest.json" 6 | }, 7 | "devDependencies": { 8 | "@types/jest": "^27.0.2", 9 | "@types/node": "^16.10.2", 10 | "@types/react": "^17.0.14", 11 | "@types/react-dom": "^17.0.9", 12 | "@types/react-redux": "^7.1.18", 13 | "@types/react-router-dom": "^5.1.8", 14 | "copy-webpack-plugin": "^9.0.1", 15 | "jest": "^27.2.4", 16 | "serve": "^12.0.1", 17 | "ts-jest": "^27.0.5", 18 | "ts-loader": "^9.2.6", 19 | "tslib": "^2.3.1", 20 | "typescript": "^4.4.3", 21 | "webpack": "^5.56.0", 22 | "webpack-cli": "^4.8.0", 23 | "webpack-dev-server": "^4.3.0" 24 | }, 25 | "dependencies": { 26 | "react": "*", 27 | "react-dom": "*", 28 | "reactant": "*", 29 | "reactant-web": "*" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/typescript/template/README.md: -------------------------------------------------------------------------------- 1 | This project was created with [Reactant CLI](https://github.com/unadlib/reactant/tree/master/packages/reactant-cli). 2 | 3 | ### Development 4 | 5 | ```bash 6 | yarn start 7 | ``` 8 | 9 | Runs the app in the development mode, and open [http://localhost:7000](http://localhost:7000) to view it in the browser. 10 | 11 | ### Build 12 | 13 | ```bash 14 | yarn build 15 | ``` 16 | 17 | Build the project, and build files are stored in the `dist/` directory. Use the `--mode=production` flag for a production build. 18 | 19 | ### Test 20 | 21 | ```bash 22 | yarn test 23 | ``` 24 | 25 | Running unit tests via [jest](https://jestjs.io). 26 | 27 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/typescript/template/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/reactant-template/templates/web/typescript/template/jest.json: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "ts-jest", 3 | "testEnvironment": "jsdom" 4 | } 5 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/typescript/template/src/app.view.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ViewModule, injectable, useConnector } from 'reactant'; 3 | import { CounterService } from './counter.service'; 4 | 5 | @injectable() 6 | class AppView extends ViewModule { 7 | constructor(public counter: CounterService) { 8 | super(); 9 | } 10 | 11 | component() { 12 | const count = useConnector(() => this.counter.count); 13 | return ( 14 | <> 15 | 18 |
{count}
19 | 22 | 23 | ); 24 | } 25 | } 26 | 27 | export { AppView }; 28 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/typescript/template/src/counter.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { testBed } from 'reactant'; 2 | import { CounterService } from './counter.service'; 3 | 4 | describe('CounterService', () => { 5 | let module: CounterService; 6 | 7 | beforeEach(() => { 8 | module = testBed({ 9 | main: CounterService, 10 | modules: [], 11 | }).instance; 12 | }); 13 | 14 | test('should be created', () => { 15 | expect(module instanceof CounterService).toBeTruthy(); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/typescript/template/src/counter.service.ts: -------------------------------------------------------------------------------- 1 | import { injectable, action, state } from 'reactant'; 2 | 3 | @injectable() 4 | class CounterService { 5 | @state 6 | count = 0; 7 | 8 | @action 9 | increase() { 10 | this.count += 1; 11 | } 12 | 13 | @action 14 | decrease() { 15 | this.count -= 1; 16 | } 17 | } 18 | 19 | export { CounterService }; 20 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/typescript/template/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/typescript/template/src/index.ts: -------------------------------------------------------------------------------- 1 | import { render } from 'reactant-web'; 2 | import { createApp } from 'reactant'; 3 | import { AppView } from './app.view'; 4 | 5 | const app = createApp({ 6 | modules: [], 7 | main: AppView, 8 | render, 9 | }); 10 | 11 | app.bootstrap(document.getElementById('app')); 12 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/typescript/template/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/", 6 | "jsx": "react", 7 | "sourceMap": true, 8 | "declaration": false, 9 | "downlevelIteration": true, 10 | "emitDecoratorMetadata": true, 11 | "experimentalDecorators": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "importHelpers": true, 15 | "target": "es2015", 16 | "typeRoots": [ 17 | "node_modules/@types" 18 | ], 19 | "allowSyntheticDefaultImports": true, 20 | "lib": [ 21 | "es2018", 22 | "dom" 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/reactant-template/templates/web/typescript/template/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 3 | 4 | module.exports = { 5 | entry: './src/index.ts', 6 | output: { 7 | path: path.resolve(__dirname, 'dist'), 8 | filename: 'bundle.js', 9 | }, 10 | module: { 11 | rules: [ 12 | { 13 | test: /\.tsx?$/, 14 | use: 'ts-loader', 15 | exclude: /node_modules/, 16 | }, 17 | ], 18 | }, 19 | resolve: { 20 | extensions: ['.tsx', '.ts', '.jsx', '.js'], 21 | }, 22 | mode: 'development', 23 | devServer: { 24 | static: { 25 | directory: path.join(__dirname, 'public'), 26 | }, 27 | compress: true, 28 | port: 7001, 29 | }, 30 | plugins: [ 31 | new CopyWebpackPlugin({ 32 | patterns: [path.join(__dirname, './src/index.html')], 33 | }), 34 | ], 35 | }; 36 | -------------------------------------------------------------------------------- /packages/reactant-web/README.md: -------------------------------------------------------------------------------- 1 | # reactant-web 2 | 3 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 4 | 5 | A Web application with react-dom for Reactant 6 | 7 | ## Usage 8 | 9 | ```bash 10 | npm install reactant-web 11 | # or 12 | yarn add reactant-web 13 | ``` 14 | 15 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 16 | -------------------------------------------------------------------------------- /packages/reactant-web/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /packages/reactant-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactant-web", 3 | "version": "0.144.0", 4 | "description": "A Web application with react-dom for Reactant", 5 | "main": "dist/index.cjs.js", 6 | "unpkg": "dist/index.umd.js", 7 | "module": "dist/index.esm.js", 8 | "types": "dist/index.d.ts", 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "keywords": [ 13 | "Reactant", 14 | "react-dom" 15 | ], 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/unadlib/reactant.git", 19 | "directory": "packages/reactant-web" 20 | }, 21 | "homepage": "https://reactant.js.org/", 22 | "authors": [ 23 | "Michael Lin (https://github.com/unadlib)" 24 | ], 25 | "license": "MIT", 26 | "peerDependencies": { 27 | "react-dom": "^16.14.0 || ^17" 28 | }, 29 | "dependencies": { 30 | "reactant-router-dom": "^0.144.0" 31 | }, 32 | "devDependencies": { 33 | "react-dom": "^17.0.2" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/reactant-web/src/index.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable camelcase */ 2 | import * as ReactDom from 'react-dom'; 3 | 4 | export type { Renderer } from 'react-dom'; 5 | 6 | export { 7 | BrowserRouter, 8 | MemoryRouter, 9 | Switch, 10 | Route, 11 | NavLink, 12 | Link, 13 | useRouteMatch, 14 | useParams, 15 | useHistory, 16 | useLocation, 17 | generatePath, 18 | Prompt, 19 | Redirect, 20 | Router, 21 | StaticRouter, 22 | matchPath, 23 | withRouter, 24 | } from 'reactant-router-dom'; 25 | 26 | export type { 27 | RedirectProps, 28 | RouteChildrenProps, 29 | RouteComponentProps, 30 | SwitchProps, 31 | match, 32 | RouterChildContext, 33 | RouteProps, 34 | } from 'reactant-router-dom'; 35 | 36 | export const { 37 | findDOMNode, 38 | unmountComponentAtNode, 39 | createPortal, 40 | version, 41 | render, 42 | hydrate, 43 | unstable_batchedUpdates, 44 | unstable_renderSubtreeIntoContainer, 45 | } = ReactDom; 46 | -------------------------------------------------------------------------------- /packages/reactant/README.md: -------------------------------------------------------------------------------- 1 | # reactant 2 | 3 | ![Node CI](https://github.com/unadlib/reactant/workflows/Node%20CI/badge.svg) 4 | 5 | A framework for building React applications 6 | 7 | ## Usage 8 | 9 | ```bash 10 | npx reactant-cli init my-app 11 | cd my-app 12 | yarn start 13 | ``` 14 | 15 | You can visit [reactant.js.org](https://reactant.js.org/) for more documentation. 16 | -------------------------------------------------------------------------------- /packages/reactant/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /packages/reactant/src/batch.ts: -------------------------------------------------------------------------------- 1 | import { batch as batchUpdateWithReact } from 'react-redux'; 2 | 3 | export const batch = batchUpdateWithReact; 4 | -------------------------------------------------------------------------------- /packages/reactant/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useConnector'; 2 | -------------------------------------------------------------------------------- /packages/reactant/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from 'reactant-module'; 2 | export * from './createApp'; 3 | export * from './testBed'; 4 | export * from './batch'; 5 | export * from './hooks/index'; 6 | export * from './interfaces'; 7 | -------------------------------------------------------------------------------- /packages/reactant/test/createApp.0.snap.tsx: -------------------------------------------------------------------------------- 1 | import { createApp, injectable } from 'reactant'; 2 | 3 | @injectable() 4 | class Foo {} 5 | 6 | const app = createApp({ 7 | modules: [], 8 | main: Foo, 9 | render: () => {}, 10 | }); 11 | 12 | expect(app.instance instanceof Foo).toBeTruthy(); 13 | -------------------------------------------------------------------------------- /packages/reactant/test/createApp.test.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { jsdocTests } from 'jsdoc-tests'; 3 | 4 | test('base "createApp" function', () => { 5 | jsdocTests('../src/createApp.tsx', __dirname); 6 | }); 7 | -------------------------------------------------------------------------------- /scripts/build.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | import path from 'path'; 3 | import { compile } from './typescript'; 4 | import { generateBundledModules } from './rollup'; 5 | import { buildTypes as buildTypesObject } from './workspaces'; 6 | 7 | process.chdir(path.resolve(__dirname, '..')); 8 | 9 | console.log(`\nBuilding...\n`); 10 | /** 11 | * sub-project set { "build": ['es', 'cjs', 'umd'] } for config about build types. 12 | */ 13 | compile(async ({ currentPath, name, packageJson }) => { 14 | const banner = packageJson.bin ? '#!/usr/bin/env node' : undefined; 15 | const { build: buildTypes = ['es', 'cjs', 'umd'] } = packageJson; 16 | for (const buildType of buildTypes) { 17 | await generateBundledModules({ 18 | inputFile: path.resolve(currentPath, 'build/index.js'), 19 | outputFile: path.resolve( 20 | currentPath, 21 | `dist/index.${buildTypesObject[buildType]}.js` 22 | ), 23 | format: buildType, 24 | name, 25 | banner, 26 | }); 27 | } 28 | }); 29 | -------------------------------------------------------------------------------- /scripts/jest/dev.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "ts-jest", 3 | "testEnvironment": "jsdom", 4 | "rootDir": "../../", 5 | "globals": { 6 | "__DEV__": true 7 | }, 8 | "transform": { 9 | "^.+\\.tsx?$": "ts-jest" 10 | }, 11 | "testPathIgnorePatterns": [ 12 | "examples", 13 | "packages/reactant-cli/templates", 14 | "packages/reactant-template/templates" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /scripts/jest/prod.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "ts-jest", 3 | "testEnvironment": "jsdom", 4 | "rootDir": "../../", 5 | "globals": { 6 | "__DEV__": false 7 | }, 8 | "transform": { 9 | "^.+\\.tsx?$": "ts-jest" 10 | }, 11 | "testPathIgnorePatterns": [ 12 | "examples", 13 | "packages/reactant-cli/templates", 14 | "packages/reactant-template/templates" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /scripts/jest/useDefineForClassFields.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "ts-jest", 3 | "testEnvironment": "jsdom", 4 | "rootDir": "../../", 5 | "globals": { 6 | "__DEV__": true 7 | }, 8 | "transform": { 9 | "^.+\\.tsx?$": [ 10 | "ts-jest", 11 | { 12 | "useDefineForClassFields": true 13 | } 14 | ] 15 | }, 16 | "testPathIgnorePatterns": [ 17 | "examples", 18 | "packages/reactant-cli/templates", 19 | "packages/reactant-template/templates" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /scripts/jest/useES2015.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "ts-jest", 3 | "testEnvironment": "jsdom", 4 | "rootDir": "../../", 5 | "globals": { 6 | "__DEV__": true 7 | }, 8 | "transform": { 9 | "^.+\\.tsx?$": [ 10 | "ts-jest", 11 | { 12 | "target": "ES2015" 13 | } 14 | ] 15 | }, 16 | "testMatch": ["**/?(*.)+(es2015).[jt]s?(x)"], 17 | "testPathIgnorePatterns": [ 18 | "examples", 19 | "packages/reactant-cli/templates", 20 | "packages/reactant-template/templates" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /scripts/performance/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unadlib/reactant/792fd8e29aa214a3e172d279f6ce82960c06ccb0/scripts/performance/index.ts -------------------------------------------------------------------------------- /scripts/workspaces.ts: -------------------------------------------------------------------------------- 1 | import globParent from 'glob-parent'; 2 | import fs from 'fs-extra'; 3 | import path from 'path'; 4 | 5 | export const buildTypes = { 6 | es: 'esm', 7 | cjs: 'cjs', 8 | umd: 'umd', 9 | } as const; 10 | 11 | export type Package = { 12 | workspaces: string[]; 13 | private: boolean; 14 | name: string; 15 | bin?: Record; 16 | build: (keyof typeof buildTypes)[]; 17 | }; 18 | 19 | export type Handler = ( 20 | packageParentDir: string, 21 | packageChildDir: string 22 | ) => Promise; 23 | 24 | export const handleWorkspaces = async (handler: Handler) => { 25 | const { workspaces }: Package = fs.readJSONSync(path.resolve('package.json')); 26 | for (const pattern of workspaces) { 27 | const packageParentDir = path.resolve(globParent(pattern)); 28 | const packageChildDirs = fs.readdirSync(packageParentDir); 29 | for (const packageChildDir of packageChildDirs) { 30 | await handler(packageParentDir, packageChildDir); 31 | } 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /website/README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. 4 | 5 | ### Installation 6 | 7 | ``` 8 | $ yarn 9 | ``` 10 | 11 | ### Local Development 12 | 13 | ``` 14 | $ yarn start 15 | ``` 16 | 17 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 18 | 19 | ### Build 20 | 21 | ``` 22 | $ yarn build 23 | ``` 24 | 25 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 26 | 27 | ### Deployment 28 | 29 | Using SSH: 30 | 31 | ``` 32 | $ USE_SSH=true yarn deploy 33 | ``` 34 | 35 | Not using SSH: 36 | 37 | ``` 38 | $ GIT_USER= yarn deploy 39 | ``` 40 | 41 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 42 | -------------------------------------------------------------------------------- /website/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /website/blog/2021-10-03-how-to-make-web-application-support-multiple-browser-windows/workflow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unadlib/reactant/792fd8e29aa214a3e172d279f6ce82960c06ccb0/website/blog/2021-10-03-how-to-make-web-application-support-multiple-browser-windows/workflow.jpg -------------------------------------------------------------------------------- /website/blog/2023-12-29-how-to-build-high-performance-front-end-applications-based-on-multi-processing/workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unadlib/reactant/792fd8e29aa214a3e172d279f6ce82960c06ccb0/website/blog/2023-12-29-how-to-build-high-performance-front-end-applications-based-on-multi-processing/workflow.png -------------------------------------------------------------------------------- /website/blog/authors.yml: -------------------------------------------------------------------------------- 1 | unadlib: 2 | name: Michael Lin 3 | title: Maintainer of Reactant 4 | url: https://github.com/unadlib 5 | image_url: https://github.com/unadlib.png 6 | -------------------------------------------------------------------------------- /website/docs/advanced-guides/dev-workflow.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 8 3 | --- 4 | 5 | # Dev Workflow 6 | 7 | ## todo 8 | -------------------------------------------------------------------------------- /website/docs/advanced-guides/di.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Dependency Injection 6 | 7 | ## API 8 | 9 | ### Class Decorators 10 | 11 | * [@injectable()](../api/reactant-module/modules/decorators_injectable.md) 12 | 13 | ### Parameter Decorators 14 | 15 | * [@inject()](../api/reactant-di/modules//decorators_inject.md) 16 | * [@optional()](../api/reactant-di/modules/decorators_optional.md) 17 | * [@multiInject()](../api/reactant-di/modules/decorators_multiInject.md) 18 | * [@multiOptional()](../api/reactant-di/modules/decorators_multiOptional.md) 19 | 20 | ### Utilities 21 | 22 | * [ModuleRef](../api/reactant-di/classes/moduleRef.ModuleRef.md) 23 | * [forwardRef()](../api/reactant-di/modules/forwardRef.md) 24 | * [Optional](../api/reactant-di/classes/optional.Optional.md) 25 | -------------------------------------------------------------------------------- /website/docs/advanced-guides/pluggable.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Pluggable 6 | 7 | `Pluggable` is an important concept of Reactant. It provides an interface that allows you to encapsulate many of React's libraries in a clean design. You can base complex plugins on it to encapsulate them simply enough. 8 | 9 | ## API 10 | 11 | * [Pluggable](../api/reactant-module/classes/core_plugin.PluginModule.md) 12 | 13 | ## Example 14 | 15 | * [reactant-router](https://github.com/unadlib/reactant/blob/master/packages/reactant-router/) 16 | * [reactant-storage](https://github.com/unadlib/reactant/blob/master/packages/reactant-storage/) 17 | -------------------------------------------------------------------------------- /website/docs/api/reactant-di/_category_.yml: -------------------------------------------------------------------------------- 1 | label: "Dependency Injection" 2 | position: 2 -------------------------------------------------------------------------------- /website/docs/api/reactant-di/classes/_category_.yml: -------------------------------------------------------------------------------- 1 | label: "Classes" 2 | position: 3 -------------------------------------------------------------------------------- /website/docs/api/reactant-di/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "index" 3 | title: "reactant-di" 4 | sidebar_label: "Table of contents" 5 | sidebar_position: 0.5 6 | hide_table_of_contents: true 7 | custom_edit_url: null 8 | --- 9 | 10 | ## Modules 11 | 12 | - [decorators/inject](modules/decorators_inject.md) 13 | - [decorators/injectable](modules/decorators_injectable.md) 14 | - [decorators/lazy](modules/decorators_lazy.md) 15 | - [decorators/multiInject](modules/decorators_multiInject.md) 16 | - [decorators/multiOptional](modules/decorators_multiOptional.md) 17 | - [decorators/optional](modules/decorators_optional.md) 18 | - [forwardRef](modules/forwardRef.md) 19 | - [moduleRef](modules/moduleRef.md) 20 | - [optional](modules/optional.md) 21 | -------------------------------------------------------------------------------- /website/docs/api/reactant-di/modules/_category_.yml: -------------------------------------------------------------------------------- 1 | label: "Modules" 2 | position: 1 -------------------------------------------------------------------------------- /website/docs/api/reactant-di/modules/decorators_multiInject.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "decorators_multiInject" 3 | title: "Module: decorators/multiInject" 4 | sidebar_label: "decorators/multiInject" 5 | sidebar_position: 0 6 | custom_edit_url: null 7 | --- 8 | 9 | ## Functions 10 | 11 | ### multiInject 12 | 13 | ▸ **multiInject**(`serviceIdentifier`): (`target`: `object`, `key?`: `string`, `index?`: `number`) => `void` 14 | 15 | #### Parameters 16 | 17 | | Name | Type | 18 | | :------ | :------ | 19 | | `serviceIdentifier` | `ServiceIdentifier`<`any`\> | 20 | 21 | #### Returns 22 | 23 | `fn` 24 | 25 | ▸ (`target`, `key?`, `index?`): `void` 26 | 27 | ##### Parameters 28 | 29 | | Name | Type | 30 | | :------ | :------ | 31 | | `target` | `object` | 32 | | `key?` | `string` | 33 | | `index?` | `number` | 34 | 35 | ##### Returns 36 | 37 | `void` 38 | 39 | #### Defined in 40 | 41 | [packages/reactant-di/src/decorators/multiInject.ts:6](https://github.com/unadlib/reactant/blob/c6e11a24/packages/reactant-di/src/decorators/multiInject.ts#L6) 42 | -------------------------------------------------------------------------------- /website/docs/api/reactant-di/modules/decorators_multiOptional.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "decorators_multiOptional" 3 | title: "Module: decorators/multiOptional" 4 | sidebar_label: "decorators/multiOptional" 5 | sidebar_position: 0 6 | custom_edit_url: null 7 | --- 8 | 9 | ## Functions 10 | 11 | ### multiOptional 12 | 13 | ▸ **multiOptional**(`serviceIdentifier`): (`target`: `object`, `key?`: `string`, `index?`: `number`) => `void` 14 | 15 | #### Parameters 16 | 17 | | Name | Type | 18 | | :------ | :------ | 19 | | `serviceIdentifier` | `ServiceIdentifier`<`any`\> | 20 | 21 | #### Returns 22 | 23 | `fn` 24 | 25 | ▸ (`target`, `key?`, `index?`): `void` 26 | 27 | ##### Parameters 28 | 29 | | Name | Type | 30 | | :------ | :------ | 31 | | `target` | `object` | 32 | | `key?` | `string` | 33 | | `index?` | `number` | 34 | 35 | ##### Returns 36 | 37 | `void` 38 | 39 | #### Defined in 40 | 41 | [packages/reactant-di/src/decorators/multiOptional.ts:7](https://github.com/unadlib/reactant/blob/c6e11a24/packages/reactant-di/src/decorators/multiOptional.ts#L7) 42 | -------------------------------------------------------------------------------- /website/docs/api/reactant-di/modules/forwardRef.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "forwardRef" 3 | title: "Module: forwardRef" 4 | sidebar_label: "forwardRef" 5 | sidebar_position: 0 6 | custom_edit_url: null 7 | --- 8 | 9 | ## Functions 10 | 11 | ### forwardRef 12 | 13 | ▸ **forwardRef**(`callback`): `LazyServiceIdentifer`<`any`\> 14 | 15 | #### Parameters 16 | 17 | | Name | Type | 18 | | :------ | :------ | 19 | | `callback` | () => `ServiceIdentifier`<`any`\> | 20 | 21 | #### Returns 22 | 23 | `LazyServiceIdentifer`<`any`\> 24 | 25 | #### Defined in 26 | 27 | [packages/reactant-di/src/forwardRef.ts:4](https://github.com/unadlib/reactant/blob/c6e11a24/packages/reactant-di/src/forwardRef.ts#L4) 28 | -------------------------------------------------------------------------------- /website/docs/api/reactant-di/modules/moduleRef.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "moduleRef" 3 | title: "Module: moduleRef" 4 | sidebar_label: "moduleRef" 5 | sidebar_position: 0 6 | custom_edit_url: null 7 | --- 8 | 9 | ## Classes 10 | 11 | - [ModuleRef](../classes/moduleRef.ModuleRef.md) 12 | -------------------------------------------------------------------------------- /website/docs/api/reactant-di/modules/optional.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "optional" 3 | title: "Module: optional" 4 | sidebar_label: "optional" 5 | sidebar_position: 0 6 | custom_edit_url: null 7 | --- 8 | 9 | ## Classes 10 | 11 | - [Optional](../classes/optional.Optional.md) 12 | 13 | ## Variables 14 | 15 | ### defaultUndefinedValue 16 | 17 | • `Const` **defaultUndefinedValue**: typeof [`defaultUndefinedValue`](optional.md#defaultundefinedvalue) 18 | 19 | #### Defined in 20 | 21 | [packages/reactant-di/src/optional.ts:3](https://github.com/unadlib/reactant/blob/c6e11a24/packages/reactant-di/src/optional.ts#L3) 22 | -------------------------------------------------------------------------------- /website/docs/api/reactant-module/_category_.yml: -------------------------------------------------------------------------------- 1 | label: "Module Model" 2 | position: 3 -------------------------------------------------------------------------------- /website/docs/api/reactant-module/classes/_category_.yml: -------------------------------------------------------------------------------- 1 | label: "Classes" 2 | position: 3 -------------------------------------------------------------------------------- /website/docs/api/reactant-module/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "index" 3 | title: "reactant-module" 4 | sidebar_label: "Table of contents" 5 | sidebar_position: 0.5 6 | hide_table_of_contents: true 7 | custom_edit_url: null 8 | --- 9 | 10 | ## Modules 11 | 12 | - [core/applyMiddleware](modules/core_applyMiddleware.md) 13 | - [core/createState](modules/core_createState.md) 14 | - [core/dispatch](modules/core_dispatch.md) 15 | - [core/load](modules/core_load.md) 16 | - [core/plugin](modules/core_plugin.md) 17 | - [core/subscribe](modules/core_subscribe.md) 18 | - [core/view](modules/core_view.md) 19 | - [core/watch](modules/core_watch.md) 20 | - [decorators/action](modules/decorators_action.md) 21 | - [decorators/autobind](modules/decorators_autobind.md) 22 | - [decorators/computed](modules/decorators_computed.md) 23 | - [decorators/injectable](modules/decorators_injectable.md) 24 | - [decorators/lazy](modules/decorators_lazy.md) 25 | - [decorators/state](modules/decorators_state.md) 26 | -------------------------------------------------------------------------------- /website/docs/api/reactant-module/modules/_category_.yml: -------------------------------------------------------------------------------- 1 | label: "Modules" 2 | position: 1 -------------------------------------------------------------------------------- /website/docs/api/reactant-module/modules/core_applyMiddleware.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "core_applyMiddleware" 3 | title: "Module: core/applyMiddleware" 4 | sidebar_label: "core/applyMiddleware" 5 | sidebar_position: 0 6 | custom_edit_url: null 7 | --- 8 | 9 | ## Functions 10 | 11 | ### applyMiddleware 12 | 13 | ▸ **applyMiddleware**(...`args`): typeof `__class` 14 | 15 | ## Description 16 | Apply middlewares for Redux. 17 | 18 | ## Example 19 | 20 | ```ts 21 | import logger from 'redux-logger'; 22 | 23 | @injectable() 24 | class Foo {} 25 | 26 | const app = createApp({ 27 | modules: [applyMiddleware(logger)], 28 | main: Foo, 29 | render: () => {}, 30 | }); 31 | ``` 32 | 33 | #### Parameters 34 | 35 | | Name | Type | Description | 36 | | :------ | :------ | :------ | 37 | | `...args` | `Middleware`<{}, `any`, `Dispatch`<`AnyAction`\>\>[] | middlewares for Redux | 38 | 39 | #### Returns 40 | 41 | typeof `__class` 42 | 43 | #### Defined in 44 | 45 | [packages/reactant-module/src/core/applyMiddleware.ts:30](https://github.com/unadlib/reactant/blob/c6e11a24/packages/reactant-module/src/core/applyMiddleware.ts#L30) 46 | -------------------------------------------------------------------------------- /website/docs/api/reactant-module/modules/core_load.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "core_load" 3 | title: "Module: core/load" 4 | sidebar_label: "core/load" 5 | sidebar_position: 0 6 | custom_edit_url: null 7 | --- 8 | 9 | ## Functions 10 | 11 | ### load 12 | 13 | ▸ **load**(`service`, `loadModules`): `Promise`<`Container`\> 14 | 15 | #### Parameters 16 | 17 | | Name | Type | 18 | | :------ | :------ | 19 | | `service` | `ThisService` | 20 | | `loadModules` | `ReactantModuleOptions`<`any`\>[] | 21 | 22 | #### Returns 23 | 24 | `Promise`<`Container`\> 25 | 26 | #### Defined in 27 | 28 | [packages/reactant-module/src/interfaces.ts:203](https://github.com/unadlib/reactant/blob/c6e11a24/packages/reactant-module/src/interfaces.ts#L203) 29 | -------------------------------------------------------------------------------- /website/docs/api/reactant-module/modules/core_plugin.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "core_plugin" 3 | title: "Module: core/plugin" 4 | sidebar_label: "core/plugin" 5 | sidebar_position: 0 6 | custom_edit_url: null 7 | --- 8 | 9 | ## Classes 10 | 11 | - [PluginModule](../classes/core_plugin.PluginModule.md) 12 | -------------------------------------------------------------------------------- /website/docs/api/reactant-module/modules/core_view.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "core_view" 3 | title: "Module: core/view" 4 | sidebar_label: "core/view" 5 | sidebar_position: 0 6 | custom_edit_url: null 7 | --- 8 | 9 | ## Classes 10 | 11 | - [ViewModule](../classes/core_view.ViewModule.md) 12 | -------------------------------------------------------------------------------- /website/docs/api/reactant-module/modules/decorators_lazy.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "decorators_lazy" 3 | title: "Module: decorators/lazy" 4 | sidebar_label: "decorators/lazy" 5 | sidebar_position: 0 6 | custom_edit_url: null 7 | --- 8 | 9 | ## Functions 10 | 11 | ### lazy 12 | 13 | ▸ **lazy**(`serviceIdentifier`, `enableCache?`): (`target`: `object`, `key`: `string` \| `symbol`, `descriptor?`: `PropertyDescriptor`<`any`\>) => `void` 14 | 15 | #### Parameters 16 | 17 | | Name | Type | 18 | | :------ | :------ | 19 | | `serviceIdentifier` | `ServiceIdentifier`<`unknown`\> | 20 | | `enableCache?` | `boolean` | 21 | 22 | #### Returns 23 | 24 | `fn` 25 | 26 | ▸ (`target`, `key`, `descriptor?`): `void` 27 | 28 | ##### Parameters 29 | 30 | | Name | Type | 31 | | :------ | :------ | 32 | | `target` | `object` | 33 | | `key` | `string` \| `symbol` | 34 | | `descriptor?` | `PropertyDescriptor`<`any`\> | 35 | 36 | ##### Returns 37 | 38 | `void` 39 | 40 | #### Defined in 41 | 42 | [packages/reactant-module/src/decorators/lazy.ts:6](https://github.com/unadlib/reactant/blob/c6e11a24/packages/reactant-module/src/decorators/lazy.ts#L6) 43 | -------------------------------------------------------------------------------- /website/docs/api/reactant-module/modules/decorators_state.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "decorators_state" 3 | title: "Module: decorators/state" 4 | sidebar_label: "decorators/state" 5 | sidebar_position: 0 6 | custom_edit_url: null 7 | --- 8 | 9 | ## Functions 10 | 11 | ### state 12 | 13 | ▸ **state**(`target`, `key`, `descriptor?`): `void` 14 | 15 | ## Description 16 | 17 | `@state` is used to decorate a class property as a state field. 18 | 19 | ## Example 20 | 21 | ```ts 22 | @injectable() 23 | class Counter { 24 | @state 25 | count = 0; 26 | } 27 | 28 | const app = testBed({ 29 | modules: [], 30 | main: Counter, 31 | }); 32 | 33 | expect(app.instance.count).toBe(0); 34 | ``` 35 | 36 | #### Parameters 37 | 38 | | Name | Type | 39 | | :------ | :------ | 40 | | `target` | `object` | 41 | | `key` | `string` \| `symbol` | 42 | | `descriptor?` | `PropertyDescriptor`<`any`\> | 43 | 44 | #### Returns 45 | 46 | `void` 47 | 48 | #### Defined in 49 | 50 | [packages/reactant-module/src/decorators/state.ts:26](https://github.com/unadlib/reactant/blob/c6e11a24/packages/reactant-module/src/decorators/state.ts#L26) 51 | -------------------------------------------------------------------------------- /website/docs/api/reactant-router/_category_.yml: -------------------------------------------------------------------------------- 1 | label: "Router" 2 | position: 5 -------------------------------------------------------------------------------- /website/docs/api/reactant-router/classes/_category_.yml: -------------------------------------------------------------------------------- 1 | label: "Classes" 2 | position: 3 -------------------------------------------------------------------------------- /website/docs/api/reactant-router/interfaces/RouterState.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "RouterState" 3 | title: "Interface: RouterState" 4 | sidebar_label: "RouterState" 5 | sidebar_position: 0 6 | custom_edit_url: null 7 | --- 8 | 9 | ## Properties 10 | 11 | ### action 12 | 13 | • **action**: `Action` 14 | 15 | #### Defined in 16 | 17 | [packages/reactant-router/src/router.tsx:26](https://github.com/unadlib/reactant/blob/c6e11a24/packages/reactant-router/src/router.tsx#L26) 18 | 19 | ___ 20 | 21 | ### location 22 | 23 | • **location**: `Location`<`unknown`\> 24 | 25 | #### Defined in 26 | 27 | [packages/reactant-router/src/router.tsx:27](https://github.com/unadlib/reactant/blob/c6e11a24/packages/reactant-router/src/router.tsx#L27) 28 | -------------------------------------------------------------------------------- /website/docs/api/reactant-router/interfaces/_category_.yml: -------------------------------------------------------------------------------- 1 | label: "Interfaces" 2 | position: 4 -------------------------------------------------------------------------------- /website/docs/api/reactant-share/_category_.yml: -------------------------------------------------------------------------------- 1 | label: "Shared App" 2 | position: 4 -------------------------------------------------------------------------------- /website/docs/api/reactant-share/classes/_category_.yml: -------------------------------------------------------------------------------- 1 | label: "Classes" 2 | position: 3 -------------------------------------------------------------------------------- /website/docs/api/reactant-share/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "index" 3 | title: "reactant-share" 4 | sidebar_label: "Table of contents" 5 | sidebar_position: 0.5 6 | hide_table_of_contents: true 7 | custom_edit_url: null 8 | --- 9 | 10 | ## Modules 11 | 12 | - [createApp](modules/createApp.md) 13 | - [delegate](modules/delegate.md) 14 | - [fork](modules/fork.md) 15 | -------------------------------------------------------------------------------- /website/docs/api/reactant-share/interfaces/_category_.yml: -------------------------------------------------------------------------------- 1 | label: "Interfaces" 2 | position: 4 -------------------------------------------------------------------------------- /website/docs/api/reactant-share/modules/_category_.yml: -------------------------------------------------------------------------------- 1 | label: "Modules" 2 | position: 1 -------------------------------------------------------------------------------- /website/docs/api/reactant-share/modules/portDetector.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "portDetector" 3 | title: "Module: portDetector" 4 | sidebar_label: "portDetector" 5 | sidebar_position: 0 6 | custom_edit_url: null 7 | --- 8 | 9 | ## Classes 10 | 11 | - [PortDetector](../classes/portDetector.PortDetector.md) 12 | -------------------------------------------------------------------------------- /website/docs/api/reactant-storage/_category_.yml: -------------------------------------------------------------------------------- 1 | label: "Storage" 2 | position: 6 -------------------------------------------------------------------------------- /website/docs/api/reactant-storage/classes/_category_.yml: -------------------------------------------------------------------------------- 1 | label: "Classes" 2 | position: 3 -------------------------------------------------------------------------------- /website/docs/api/reactant-storage/interfaces/_category_.yml: -------------------------------------------------------------------------------- 1 | label: "Interfaces" 2 | position: 4 -------------------------------------------------------------------------------- /website/docs/api/reactant/_category_.yml: -------------------------------------------------------------------------------- 1 | label: "Base" 2 | position: 1 -------------------------------------------------------------------------------- /website/docs/api/reactant/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: "index" 3 | title: "reactant" 4 | sidebar_label: "Table of contents" 5 | sidebar_position: 0.5 6 | hide_table_of_contents: true 7 | custom_edit_url: null 8 | --- 9 | 10 | ## Modules 11 | 12 | - [createApp](modules/createApp.md) 13 | - [hooks/useConnector](modules/hooks_useConnector.md) 14 | - [testBed](modules/testBed.md) 15 | -------------------------------------------------------------------------------- /website/docs/api/reactant/modules/_category_.yml: -------------------------------------------------------------------------------- 1 | label: "Modules" 2 | position: 1 -------------------------------------------------------------------------------- /website/docs/basic-tutorial/component.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # React Component 6 | 7 | Reactant advocates separation of concern, so we recommend that components should have as little business logic as possible and make the [React components](https://reactjs.org/docs/react-component.html) as pure as possible; we also advocate using Function components and using a [React hook](https://reactjs.org/docs/hooks-intro.html) whenever possible. 8 | 9 | In Reactant's View Module, React components can also be injected by the original dependency module, depending on your abstract understanding of the current View Module. 10 | -------------------------------------------------------------------------------- /website/docs/resources/examples.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Examples 6 | 7 | ## Online Examples 8 | 9 | * [TodoMVC](https://stackblitz.com/edit/reactant-todomvc) 10 | * [bookstore](https://stackblitz.com/edit/reactant-bookstore-example) 11 | * [counter](https://stackblitz.com/edit/reactant-ts) 12 | 13 | ## Example Repo 14 | 15 | ### Web 16 | 17 | * [counter-ts](https://github.com/unadlib/reactant-examples/tree/master/web/counter-ts) 18 | * [counter-js](https://github.com/unadlib/reactant-examples/tree/master/web/counter-js) 19 | 20 | ## Mobile 21 | 22 | * [counter-js](https://github.com/unadlib/reactant-examples/tree/master/counter-js) 23 | * [counter-ts](https://github.com/unadlib/reactant-examples/tree/master/counter-js) 24 | 25 | > For more examples, visit [reactant-examples](https://github.com/unadlib/reactant-examples) 26 | -------------------------------------------------------------------------------- /website/docs/resources/performance.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Performance 6 | 7 | todo 8 | -------------------------------------------------------------------------------- /website/docs/shared-app/img/workflow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unadlib/reactant/792fd8e29aa214a3e172d279f6ce82960c06ccb0/website/docs/shared-app/img/workflow.jpg -------------------------------------------------------------------------------- /website/docs/shared-app/shared-app- isolated-state.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Shared App Isolated State 6 | 7 | ## Examples 8 | 9 | -------------------------------------------------------------------------------- /website/docs/shared-app/shared-app-coworker.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Shared App Coworker 6 | 7 | ## Examples 8 | 9 | -------------------------------------------------------------------------------- /website/docs/shared-app/shared-app-persistence.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Persistence 6 | 7 | ## Examples 8 | -------------------------------------------------------------------------------- /website/docs/shared-app/shared-app-routing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Shared App Routing 6 | 7 | ## Examples 8 | 9 | -------------------------------------------------------------------------------- /website/docs/tooling/dev-tools.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Dev Tools 6 | 7 | ## Todo 8 | 9 | * Browser dev tools 10 | * VS Code dev extensions 11 | * C4 model tools 12 | * Bundler 13 | * SSR 14 | -------------------------------------------------------------------------------- /website/src/components/HomepageFeatures/styles.module.css: -------------------------------------------------------------------------------- 1 | .features { 2 | display: flex; 3 | align-items: center; 4 | padding: 2rem 0; 5 | width: 100%; 6 | } 7 | 8 | .featureSvg { 9 | height: 200px; 10 | width: 200px; 11 | } 12 | -------------------------------------------------------------------------------- /website/src/css/custom.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Any CSS included here will be global. The classic template 3 | * bundles Infima by default. Infima is a CSS framework designed to 4 | * work well for content-centric websites. 5 | */ 6 | 7 | /* You can override the default Infima variables here. */ 8 | :root { 9 | --ifm-color-primary: #0095ff; 10 | --ifm-color-primary-dark: #0086e6; 11 | --ifm-color-primary-darker: #007fd9; 12 | --ifm-color-primary-darkest: #0068b3; 13 | --ifm-color-primary-light: #1aa0ff; 14 | --ifm-color-primary-lighter: #26a5ff; 15 | --ifm-color-primary-lightest: #4db5ff; 16 | --ifm-code-font-size: 95%; 17 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); 18 | } 19 | 20 | /* For readability concerns, you should choose a lighter palette in dark mode. */ 21 | [data-theme='dark'] { 22 | --ifm-color-primary: #3fa9f5; 23 | --ifm-color-primary-dark: #229cf3; 24 | --ifm-color-primary-darker: #1395f3; 25 | --ifm-color-primary-darkest: #0b7ccd; 26 | --ifm-color-primary-light: #5cb6f7; 27 | --ifm-color-primary-lighter: #6bbdf7; 28 | --ifm-color-primary-lightest: #97d0fa; 29 | } 30 | -------------------------------------------------------------------------------- /website/src/pages/index.module.css: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS files with the .module.css suffix will be treated as CSS modules 3 | * and scoped locally. 4 | */ 5 | 6 | .heroBanner { 7 | padding: 4rem 0; 8 | text-align: center; 9 | position: relative; 10 | overflow: hidden; 11 | } 12 | 13 | @media screen and (max-width: 996px) { 14 | .heroBanner { 15 | padding: 2rem; 16 | } 17 | } 18 | 19 | .buttons { 20 | display: flex; 21 | align-items: center; 22 | justify-content: center; 23 | } 24 | 25 | .particlesContainer { 26 | position: absolute; 27 | width: 100%; 28 | } 29 | 30 | .container { 31 | position: relative; 32 | } 33 | -------------------------------------------------------------------------------- /website/src/pages/markdown-page.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Markdown page example 3 | --- 4 | 5 | # Markdown page example 6 | 7 | You don't need React to write simple standalone pages. 8 | -------------------------------------------------------------------------------- /website/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unadlib/reactant/792fd8e29aa214a3e172d279f6ce82960c06ccb0/website/static/.nojekyll -------------------------------------------------------------------------------- /website/static/CNAME: -------------------------------------------------------------------------------- 1 | reactant.js.org -------------------------------------------------------------------------------- /website/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unadlib/reactant/792fd8e29aa214a3e172d279f6ce82960c06ccb0/website/static/img/favicon.ico -------------------------------------------------------------------------------- /website/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // This file is not used in compilation. It is here just for a nice editor experience. 3 | "extends": "@tsconfig/docusaurus/tsconfig.json", 4 | "compilerOptions": { 5 | "baseUrl": "." 6 | } 7 | } 8 | --------------------------------------------------------------------------------