├── .changeset └── config.json ├── .circleci └── config.yml ├── .eslintignore ├── .eslintrc.js ├── .github ├── ISSUE_TEMPLATE │ ├── SUPPORT.md │ ├── bug_report.md │ ├── custom.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── release.yaml │ └── test-all-packages.yaml ├── .gitignore ├── .prettierignore ├── .prettierrc ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── benchmark ├── .env ├── README.md ├── benchmarks │ ├── benchmarkManager.ts │ ├── react │ │ ├── 1000fields │ │ │ ├── bench │ │ │ │ ├── agilets │ │ │ │ │ ├── collection.tsx │ │ │ │ │ ├── nestedState.tsx │ │ │ │ │ └── state.tsx │ │ │ │ ├── hookstate.tsx │ │ │ │ ├── jotai.tsx │ │ │ │ ├── mobx.tsx │ │ │ │ ├── nanostores.tsx │ │ │ │ ├── pulsejs │ │ │ │ │ ├── collection.tsx │ │ │ │ │ ├── nestedState.tsx │ │ │ │ │ └── state.tsx │ │ │ │ ├── recoil.tsx │ │ │ │ ├── redux.tsx │ │ │ │ └── valtio.tsx │ │ │ └── index.ts │ │ ├── computed │ │ │ ├── bench │ │ │ │ ├── agilets │ │ │ │ │ ├── autoTracking.tsx │ │ │ │ │ └── hardCoded.tsx │ │ │ │ ├── jotai.tsx │ │ │ │ ├── nanostores.tsx │ │ │ │ └── recoil.tsx │ │ │ └── index.ts │ │ └── counter │ │ │ ├── bench │ │ │ ├── agilets.tsx │ │ │ ├── hookstate.tsx │ │ │ ├── jotai.tsx │ │ │ ├── mobx.tsx │ │ │ ├── nanostores.tsx │ │ │ ├── pulsejs.tsx │ │ │ ├── recoil.tsx │ │ │ ├── redux-toolkit.tsx │ │ │ ├── redux.tsx │ │ │ ├── valtio.tsx │ │ │ └── zustand.tsx │ │ │ └── index.ts │ └── typescript │ │ ├── cloneDeep │ │ ├── bench │ │ │ ├── lodash.ts │ │ │ ├── looper.ts │ │ │ └── stringify.ts │ │ └── index.ts │ │ └── defineConfig │ │ ├── bench │ │ ├── referencer.ts │ │ ├── spreadReferencer.ts │ │ └── spreader.ts │ │ └── index.ts ├── lodash.ts ├── package.json ├── public │ └── index.html ├── runtime │ ├── benchmarkTypes.ts │ └── run.ts ├── tsconfig.json └── yarn.lock ├── examples ├── README.md ├── nextjs │ └── develop │ │ ├── clock │ │ ├── .eslintrc │ │ ├── .gitignore │ │ ├── README.md │ │ ├── components │ │ │ ├── Clock.tsx │ │ │ ├── Counter.tsx │ │ │ ├── Nav.tsx │ │ │ └── Page.tsx │ │ ├── next-env.d.ts │ │ ├── next.config.js │ │ ├── package.json │ │ ├── pages │ │ │ ├── _app.tsx │ │ │ ├── index.tsx │ │ │ ├── ssg.tsx │ │ │ └── ssr.tsx │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── vercel.svg │ │ ├── src │ │ │ ├── core.ts │ │ │ └── useInterval.ts │ │ ├── styles │ │ │ └── globals.css │ │ ├── tsconfig.json │ │ └── yarn.lock │ │ └── counter │ │ ├── .eslintrc │ │ ├── .gitignore │ │ ├── README.md │ │ ├── components │ │ └── Counter.tsx │ │ ├── next-env.d.ts │ │ ├── next.config.js │ │ ├── package.json │ │ ├── pages │ │ ├── _app.tsx │ │ └── index.tsx │ │ ├── public │ │ ├── favicon.ico │ │ └── vercel.svg │ │ ├── src │ │ └── core.ts │ │ ├── styles │ │ └── globals.css │ │ ├── tsconfig.json │ │ └── yarn.lock ├── plainjs │ └── develop │ │ └── tree-shaking │ │ ├── .gitignore │ │ ├── package.json │ │ ├── src │ │ └── index.js │ │ └── webpack.config.js ├── razzle │ └── develop │ │ └── counter │ │ ├── .gitignore │ │ ├── README.md │ │ ├── package.json │ │ ├── public │ │ ├── favicon.ico │ │ └── robots.txt │ │ ├── sandbox.config.json │ │ ├── src │ │ ├── App.js │ │ ├── client.js │ │ ├── components │ │ │ └── Counter.js │ │ ├── core │ │ │ └── index.js │ │ ├── index.js │ │ └── server.js │ │ └── yarn.lock ├── react-native │ ├── README.md │ └── develop │ │ └── AwesomeTSProject │ │ ├── .buckconfig │ │ ├── .eslintrc.js │ │ ├── .gitattributes │ │ ├── .gitignore │ │ ├── .watchmanconfig │ │ ├── App.tsx │ │ ├── README.md │ │ ├── android │ │ ├── app │ │ │ ├── _BUCK │ │ │ ├── build.gradle │ │ │ ├── build_defs.bzl │ │ │ ├── debug.keystore │ │ │ ├── proguard-rules.pro │ │ │ └── src │ │ │ │ ├── debug │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── awesometsproject │ │ │ │ │ └── ReactNativeFlipper.java │ │ │ │ └── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── awesometsproject │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── MainApplication.java │ │ │ │ └── res │ │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ └── values │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ ├── build.gradle │ │ ├── gradle.properties │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle │ │ ├── app.json │ │ ├── babel.config.js │ │ ├── core │ │ └── index.ts │ │ ├── index.js │ │ ├── ios │ │ ├── AwesomeTSProject-tvOS │ │ │ └── Info.plist │ │ ├── AwesomeTSProject-tvOSTests │ │ │ └── Info.plist │ │ ├── AwesomeTSProject.xcodeproj │ │ │ ├── project.pbxproj │ │ │ └── xcshareddata │ │ │ │ └── xcschemes │ │ │ │ ├── AwesomeTSProject-tvOS.xcscheme │ │ │ │ └── AwesomeTSProject.xcscheme │ │ ├── AwesomeTSProject.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── AwesomeTSProject │ │ │ ├── AppDelegate.h │ │ │ ├── AppDelegate.m │ │ │ ├── Images.xcassets │ │ │ │ ├── AppIcon.appiconset │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ ├── Info.plist │ │ │ ├── LaunchScreen.storyboard │ │ │ └── main.m │ │ ├── AwesomeTSProjectTests │ │ │ ├── AwesomeTSProjectTests.m │ │ │ └── Info.plist │ │ ├── Podfile │ │ └── Podfile.lock │ │ ├── metro.config.js │ │ ├── package.json │ │ ├── tsconfig.json │ │ └── yarn.lock ├── react │ ├── README.md │ ├── develop │ │ ├── class-component-ts │ │ │ ├── .env │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── public │ │ │ │ ├── favicon.ico │ │ │ │ ├── index.html │ │ │ │ ├── logo192.png │ │ │ │ ├── logo512.png │ │ │ │ ├── manifest.json │ │ │ │ └── robots.txt │ │ │ ├── src │ │ │ │ ├── App.css │ │ │ │ ├── App.tsx │ │ │ │ ├── core │ │ │ │ │ └── index.ts │ │ │ │ ├── index.css │ │ │ │ ├── index.tsx │ │ │ │ └── react-app-env.d.ts │ │ │ ├── tsconfig.json │ │ │ └── yarn.lock │ │ ├── fields │ │ │ ├── .env │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── public │ │ │ │ ├── favicon.ico │ │ │ │ ├── index.html │ │ │ │ ├── logo192.png │ │ │ │ ├── logo512.png │ │ │ │ ├── manifest.json │ │ │ │ └── robots.txt │ │ │ └── src │ │ │ │ ├── App.js │ │ │ │ └── index.js │ │ ├── functional-component-ts │ │ │ ├── .env │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── public │ │ │ │ ├── favicon.ico │ │ │ │ ├── index.html │ │ │ │ ├── logo192.png │ │ │ │ ├── logo512.png │ │ │ │ ├── manifest.json │ │ │ │ └── robots.txt │ │ │ ├── src │ │ │ │ ├── App.css │ │ │ │ ├── App.tsx │ │ │ │ ├── core │ │ │ │ │ └── index.ts │ │ │ │ ├── index.css │ │ │ │ ├── index.tsx │ │ │ │ └── react-app-env.d.ts │ │ │ ├── tsconfig.json │ │ │ └── yarn.lock │ │ ├── multieditor-ts │ │ │ ├── .env │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── public │ │ │ │ ├── favicon.ico │ │ │ │ ├── index.html │ │ │ │ ├── logo192.png │ │ │ │ ├── logo512.png │ │ │ │ ├── manifest.json │ │ │ │ └── robots.txt │ │ │ ├── src │ │ │ │ ├── App.css │ │ │ │ ├── App.tsx │ │ │ │ ├── components │ │ │ │ │ └── ErrorMessage.tsx │ │ │ │ ├── core │ │ │ │ │ ├── signUpEditor.ts │ │ │ │ │ └── utils.ts │ │ │ │ ├── index.css │ │ │ │ ├── index.tsx │ │ │ │ └── react-app-env.d.ts │ │ │ ├── tsconfig.json │ │ │ └── yarn.lock │ │ ├── simple-counter │ │ │ ├── .env │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── public │ │ │ │ ├── favicon.ico │ │ │ │ ├── index.html │ │ │ │ ├── manifest.json │ │ │ │ └── robots.txt │ │ │ ├── scripts │ │ │ │ └── analyze.js │ │ │ ├── src │ │ │ │ ├── index.js │ │ │ │ └── state-manager │ │ │ │ │ ├── Agile.js │ │ │ │ │ ├── Hookstate.js │ │ │ │ │ ├── Jotai.js │ │ │ │ │ ├── NanoStores.js │ │ │ │ │ ├── Recoil.js │ │ │ │ │ └── ReduxToolkit.js │ │ │ └── yarn.lock │ │ ├── simple-todo-list │ │ │ ├── .env │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── public │ │ │ │ ├── favicon.ico │ │ │ │ ├── index.html │ │ │ │ ├── logo192.png │ │ │ │ ├── logo512.png │ │ │ │ ├── manifest.json │ │ │ │ └── robots.txt │ │ │ └── src │ │ │ │ ├── App.js │ │ │ │ ├── core.js │ │ │ │ └── index.js │ │ ├── spacex-graphql │ │ │ ├── .env │ │ │ ├── .eslintrc.js │ │ │ ├── .gitignore │ │ │ ├── .prettierignore │ │ │ ├── .prettierrc │ │ │ ├── package.json │ │ │ ├── public │ │ │ │ ├── favicon.ico │ │ │ │ ├── index.html │ │ │ │ ├── logo192.png │ │ │ │ ├── logo512.png │ │ │ │ ├── manifest.json │ │ │ │ └── robots.txt │ │ │ ├── src │ │ │ │ ├── core │ │ │ │ │ ├── apolloTest.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── global.css │ │ │ │ ├── index.tsx │ │ │ │ ├── pages │ │ │ │ │ └── Home │ │ │ │ │ │ ├── Home.module.css │ │ │ │ │ │ └── index.tsx │ │ │ │ └── react-app-env.d.ts │ │ │ ├── tsconfig.json │ │ │ └── yarn.lock │ │ └── tree-shaking │ │ │ ├── package.json │ │ │ ├── src │ │ │ ├── App.jsx │ │ │ ├── core.js │ │ │ └── index.js │ │ │ └── webpack.config.js │ └── release │ │ ├── boxes │ │ ├── .env │ │ ├── .gitignore │ │ ├── package.json │ │ ├── public │ │ │ ├── favicon.ico │ │ │ ├── index.html │ │ │ ├── logo192.png │ │ │ ├── logo512.png │ │ │ ├── manifest.json │ │ │ └── robots.txt │ │ ├── src │ │ │ ├── App.tsx │ │ │ ├── api.ts │ │ │ ├── components │ │ │ │ ├── BounceSpinner.tsx │ │ │ │ ├── Rectangle │ │ │ │ │ ├── components │ │ │ │ │ │ ├── RectangleContainer.tsx │ │ │ │ │ │ ├── RectangleInner.tsx │ │ │ │ │ │ └── RectangleLoading.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── Spacer.tsx │ │ │ │ └── actionComponents │ │ │ │ │ ├── Drag.tsx │ │ │ │ │ └── Resize │ │ │ │ │ ├── components │ │ │ │ │ └── Handle.tsx │ │ │ │ │ ├── controller.ts │ │ │ │ │ └── index.tsx │ │ │ ├── core │ │ │ │ ├── app.ts │ │ │ │ ├── entities │ │ │ │ │ └── ui │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── ui.actions.ts │ │ │ │ │ │ ├── ui.controller.ts │ │ │ │ │ │ └── ui.interfaces.ts │ │ │ │ └── index.ts │ │ │ ├── global.css │ │ │ ├── hooks │ │ │ │ ├── useRandomBorderRadius.ts │ │ │ │ └── useWindowSize.ts │ │ │ ├── index.tsx │ │ │ ├── react-app-env.d.ts │ │ │ └── screens │ │ │ │ └── Canvas │ │ │ │ ├── components │ │ │ │ ├── CanvasContainer.tsx │ │ │ │ ├── EditProperties │ │ │ │ │ ├── components │ │ │ │ │ │ ├── Card.tsx │ │ │ │ │ │ ├── ImageInfo │ │ │ │ │ │ │ ├── components │ │ │ │ │ │ │ │ └── Info.tsx │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── Property │ │ │ │ │ │ │ ├── components │ │ │ │ │ │ │ │ └── PropertyInput.tsx │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ └── Section.tsx │ │ │ │ │ └── index.tsx │ │ │ │ └── Toolbar.tsx │ │ │ │ └── index.tsx │ │ ├── tsconfig.json │ │ └── yarn.lock │ │ └── stopwatch-query-url │ │ ├── .env │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── .prettierignore │ │ ├── .prettierrc │ │ ├── package.json │ │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── robots.txt │ │ ├── src │ │ ├── components │ │ │ └── Stopwatch │ │ │ │ ├── Stopwatch.module.css │ │ │ │ ├── components │ │ │ │ └── Button │ │ │ │ │ ├── Button.module.css │ │ │ │ │ └── index.tsx │ │ │ │ └── index.tsx │ │ ├── core │ │ │ └── index.ts │ │ ├── global.css │ │ ├── index.tsx │ │ ├── pages │ │ │ └── Home │ │ │ │ ├── Home.module.css │ │ │ │ └── index.tsx │ │ └── react-app-env.d.ts │ │ ├── tsconfig.json │ │ └── yarn.lock └── vue │ └── develop │ └── my-project │ ├── .gitignore │ ├── README.md │ ├── babel.config.js │ ├── package.json │ ├── public │ ├── favicon.ico │ └── index.html │ ├── src │ ├── App.vue │ ├── assets │ │ └── logo.png │ ├── components │ │ └── HelloWorld.vue │ ├── core.js │ └── main.js │ └── yarn.lock ├── jest.base.config.js ├── jest.config.js ├── lerna.json ├── package.json ├── packages ├── api │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── babel.config.js ├── core │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── rollup.config.js │ ├── scripts │ │ └── prepublish.js │ ├── src │ │ ├── agile.ts │ │ ├── collection │ │ │ ├── collection.persistent.ts │ │ │ ├── collection.ts │ │ │ ├── group │ │ │ │ ├── group.observer.ts │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── item │ │ │ │ └── index.ts │ │ │ ├── public │ │ │ │ ├── createCollection.ts │ │ │ │ └── index.ts │ │ │ └── selector │ │ │ │ └── index.ts │ │ ├── computed │ │ │ ├── computed.tracker.ts │ │ │ ├── computed.ts │ │ │ ├── index.ts │ │ │ └── public │ │ │ │ ├── createComputed.ts │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ ├── index.ts │ │ ├── integrations │ │ │ ├── index.ts │ │ │ ├── integration.ts │ │ │ └── integrations.ts │ │ ├── logCodeManager.ts │ │ ├── runtime │ │ │ ├── index.ts │ │ │ ├── observer.ts │ │ │ ├── runtime.job.ts │ │ │ ├── runtime.ts │ │ │ └── subscription │ │ │ │ ├── container │ │ │ │ ├── CallbackSubscriptionContainer.ts │ │ │ │ ├── ComponentSubscriptionContainer.ts │ │ │ │ └── SubscriptionContainer.ts │ │ │ │ ├── index.ts │ │ │ │ └── sub.controller.ts │ │ ├── shared.ts │ │ ├── state │ │ │ ├── index.ts │ │ │ ├── public │ │ │ │ ├── createEnhancedState.ts │ │ │ │ ├── createLightState.ts │ │ │ │ ├── createState.ts │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── state.enhanced.ts │ │ │ ├── state.observer.ts │ │ │ ├── state.persistent.ts │ │ │ ├── state.runtime.job.ts │ │ │ └── state.ts │ │ ├── storages │ │ │ ├── index.ts │ │ │ ├── persistent.ts │ │ │ ├── shared.ts │ │ │ ├── storage.ts │ │ │ └── storages.ts │ │ └── utils.ts │ ├── tests │ │ ├── helper │ │ │ ├── logMock.ts │ │ │ └── test.integration.ts │ │ ├── integration │ │ │ └── collection.persistent.integration.test.ts │ │ └── unit │ │ │ ├── agile.test.ts │ │ │ ├── collection │ │ │ ├── collection.persistent.test.ts │ │ │ ├── collection.test.ts │ │ │ ├── group │ │ │ │ ├── group.observer.test.ts │ │ │ │ └── group.test.ts │ │ │ ├── index.test.ts │ │ │ ├── item.test.ts │ │ │ └── selector.test.ts │ │ │ ├── computed │ │ │ ├── computed.test.ts │ │ │ ├── computed.tracker.test.ts │ │ │ └── index.test.ts │ │ │ ├── integrations │ │ │ ├── integration.test.ts │ │ │ └── integrations.test.ts │ │ │ ├── runtime │ │ │ ├── observer.test.ts │ │ │ ├── runtime.job.test.ts │ │ │ ├── runtime.test.ts │ │ │ └── subscription │ │ │ │ ├── container │ │ │ │ ├── CallbackSubscriptionContainer.test.ts │ │ │ │ ├── ComponentSubscriptionContainer.test.ts │ │ │ │ └── SubscriptionContainer.test.ts │ │ │ │ └── sub.controller.test.ts │ │ │ ├── shared.test.ts │ │ │ ├── state │ │ │ ├── index.test.ts │ │ │ ├── state.enhanced.test.ts │ │ │ ├── state.observer.test.ts │ │ │ ├── state.persistent.test.ts │ │ │ ├── state.runtime.job.test.ts │ │ │ └── state.test.ts │ │ │ ├── storages │ │ │ ├── index.test.ts │ │ │ ├── persistent.test.ts │ │ │ ├── shared.test.ts │ │ │ ├── storage.test.ts │ │ │ └── storages.test.ts │ │ │ └── utils.test.ts │ └── tsconfig.json ├── cra-template-agile-typescript │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── template.json │ └── template │ │ ├── .eslintrc.js │ │ ├── .prettierignore │ │ ├── .prettierrc │ │ ├── gitignore │ │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── robots.txt │ │ ├── src │ │ ├── components │ │ │ └── Stopwatch │ │ │ │ ├── Stopwatch.module.css │ │ │ │ ├── components │ │ │ │ └── Button │ │ │ │ │ ├── Button.module.css │ │ │ │ │ └── index.tsx │ │ │ │ └── index.tsx │ │ ├── core │ │ │ └── index.ts │ │ ├── global.css │ │ ├── index.tsx │ │ ├── pages │ │ │ └── Home │ │ │ │ ├── Home.module.css │ │ │ │ └── index.tsx │ │ └── react-app-env.d.ts │ │ └── tsconfig.json ├── cra-template-agile │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── template.json │ └── template │ │ ├── .eslintrc.js │ │ ├── .prettierignore │ │ ├── .prettierrc │ │ ├── gitignore │ │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── robots.txt │ │ └── src │ │ ├── components │ │ └── Stopwatch │ │ │ ├── Stopwatch.module.css │ │ │ ├── components │ │ │ └── Button │ │ │ │ ├── Button.module.css │ │ │ │ └── index.jsx │ │ │ └── index.jsx │ │ ├── core │ │ └── index.js │ │ ├── global.css │ │ ├── index.jsx │ │ └── pages │ │ └── Home │ │ ├── Home.module.css │ │ └── index.jsx ├── event │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ ├── event.observer.ts │ │ ├── event.runtime.job.ts │ │ ├── event.ts │ │ └── index.ts │ ├── tests │ │ └── unit │ │ │ └── event │ │ │ ├── event.job.test.ts │ │ │ ├── event.observer.test.ts │ │ │ ├── event.test.ts │ │ │ └── index.test.ts │ └── tsconfig.json ├── logger │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ ├── index.ts │ │ ├── logger.ts │ │ └── shared.ts │ └── tsconfig.json ├── multieditor │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ ├── index.ts │ │ ├── item.ts │ │ ├── logCodeManager.ts │ │ ├── multieditor │ │ │ ├── index.ts │ │ │ ├── multieditor.ts │ │ │ └── types.ts │ │ ├── status │ │ │ ├── index.ts │ │ │ ├── status.tracker.ts │ │ │ └── status.ts │ │ ├── utils.ts │ │ └── validator │ │ │ ├── index.ts │ │ │ ├── resolvers │ │ │ ├── agile │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ └── yup │ │ │ │ └── index.ts │ │ │ ├── validationMethods │ │ │ ├── general.ts │ │ │ ├── number.ts │ │ │ └── string.ts │ │ │ └── validator.ts │ └── tsconfig.json ├── proxytree │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ ├── index.ts │ │ ├── tree │ │ │ ├── branch.ts │ │ │ └── index.ts │ │ └── utils.ts │ ├── static │ │ └── pathTrackingImage.jpg │ ├── tests │ │ └── unit │ │ │ └── tree.test.ts │ └── tsconfig.json ├── react │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ ├── core │ │ │ ├── hocs │ │ │ │ └── AgileHOC.ts │ │ │ ├── hooks │ │ │ │ ├── useAgile.ts │ │ │ │ ├── useBaseAgile.ts │ │ │ │ ├── useSelector.ts │ │ │ │ ├── useValue.ts │ │ │ │ └── useWatcher.ts │ │ │ └── index.ts │ │ ├── event │ │ │ ├── eventPackage.ts │ │ │ ├── hooks │ │ │ │ └── useEvent.ts │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── logCodeManager.ts │ │ ├── multieditor │ │ │ ├── hooks │ │ │ │ └── useMultieditor.ts │ │ │ ├── index.ts │ │ │ └── multieditorPackage.ts │ │ ├── proxy │ │ │ ├── hooks │ │ │ │ └── useProxy.ts │ │ │ ├── index.ts │ │ │ └── proxyPackage.ts │ │ ├── react.integration.ts │ │ └── utils │ │ │ ├── hooks │ │ │ └── useIsomorphicLayoutEffect.ts │ │ │ └── index.ts │ ├── static │ │ ├── contribute_header.png │ │ ├── documentation_header.png │ │ ├── header_background.png │ │ ├── installation_header.png │ │ └── what_does_this_integration_header.png │ ├── tests │ │ └── old │ │ │ └── useAgile.spec.ts │ └── tsconfig.json ├── rollup.config.default.js ├── tsconfig.default.json ├── utils │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ └── index.ts │ ├── tests │ │ └── unit │ │ │ └── utils.test.ts │ └── tsconfig.json └── vue │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── rollup.config.js │ ├── src │ ├── bindAgileInstances.ts │ ├── index.ts │ └── vue.integration.ts │ ├── static │ ├── contribute_header.png │ ├── documentation_header.png │ ├── header_background.png │ ├── installation_header.png │ └── what_does_this_integration_header.png │ └── tsconfig.json ├── static ├── branch_organization.png ├── contribute_header.png ├── credits_header.png ├── documentation_header.png ├── header_background.png ├── how_to_create_state_header.png ├── installation_header.png ├── packages_of_agile.png └── why_should_i_use_agile.png └── yarn.lock /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@1.4.0/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "linked": [], 6 | "access": "restricted", 7 | "baseBranch": "master", 8 | "updateInternalDependencies": "patch", 9 | "ignore": [] 10 | } -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | .eslintrc.js 4 | jest.config.js 5 | jest.base.config.js 6 | scripts/ 7 | examples/ 8 | 9 | # Ignore the templates (because otherwise it will try to lint with the eslint config of these packages) 10 | cra-template-agile-typescript/ 11 | cra-template-agile/ 12 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | const OFF = 0; 2 | const WARNING = 1; 3 | const ERROR = 2; 4 | 5 | module.exports = { 6 | root: true, 7 | env: { 8 | browser: true, 9 | commonjs: true, 10 | jest: true, 11 | node: true, 12 | }, 13 | extends: [ 14 | 'eslint:recommended', 15 | 'plugin:@typescript-eslint/recommended', 16 | 'prettier', 17 | ], 18 | plugins: ['@typescript-eslint', 'prettier'], 19 | parser: '@typescript-eslint/parser', 20 | parserOptions: { 21 | allowImportExportEverywhere: true, 22 | ecmaVersion: 12, 23 | sourceType: 'module', 24 | }, 25 | ignorePatterns: ['.eslintrc.js'], 26 | rules: { 27 | 'func-names': OFF, 28 | '@typescript-eslint/no-explicit-any': OFF, 29 | '@typescript-eslint/explicit-module-boundary-types': OFF, 30 | '@typescript-eslint/ban-types': WARNING, 31 | '@typescript-eslint/ban-ts-comment': WARNING, 32 | }, 33 | }; 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/SUPPORT.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🆘 Support, Help, and Advice 3 | about: 👉🏽 Need help or tech support? Please don't open an issue! Head to https://github.com/agile-ts/agile/discussions or https://stackoverflow.com/questions/tagged/agile-ts. 4 | --- 5 | 6 | Hey there! If you need help or tech support then this is not the place to ask. 7 | Please head to the [AgileTs Discord](https://discord.com/T9GzreAwPH) instead 8 | or post a question to [Stackoverflow](https://stackoverflow.com/questions/tagged/agile-ts). 9 | 10 | If you arrived here because you think AgileTs's documentation is unclear, 11 | insufficient or wrong, please consider creating an issue for the documentation [here](https://github.com/agile-ts/documentation) instead. 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🔨 Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🆕 Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: 'Type: Enhancement' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## 🆕 Feature Request 11 | 12 | ### ❓ Is your feature request related to a problem? 13 | 14 | 15 | ### 📄 Describe the solution you'd like 16 | 17 | 18 | ### 📃 Describe alternatives you've considered 19 | 20 | 21 | ### ➕ Additional Notes 22 | 23 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 📄 Description 4 | 5 | 6 | ## 🔴 Related Issue 7 | 8 | 9 | 10 | ## 📃 Context 11 | 12 | 13 | 14 | ## 🛠 How Has This Been Tested? 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: 4 | branches: [master] 5 | 6 | jobs: 7 | release: 8 | name: Release 9 | runs-on: ubuntu-latest 10 | steps: 11 | # Checkout Project 12 | - name: 📚 Checkout 13 | uses: actions/checkout@v2 14 | 15 | # Setup NodeJS 16 | - name: 🟢 Setup Node ${{ matrix.node_version }} 17 | uses: actions/setup-node@v1 18 | with: 19 | node-version: 12 20 | 21 | # Install Dependencies 22 | - name: ⏳ Install 23 | run: yarn install 24 | 25 | # Create Release Pull Request 26 | - name: 📤 Create Release Pull Request or Publish to NPM 27 | uses: changesets/action@master 28 | with: 29 | publish: yarn release:prepare 30 | commit: Version Release 31 | title: Next Release 32 | env: 33 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 34 | NPM_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | # Differs on each engine 4 | yalc.lock 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | .eslintcache 15 | package-lock.json 16 | 17 | # Editor directories and files 18 | .idea 19 | .vscode 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw* 25 | sync.js 26 | *.log 27 | 28 | # Generated files from build 29 | src/*.js 30 | src/*.js.map 31 | *.tgz 32 | cache 33 | coverage 34 | .yalc 35 | dist 36 | .changelog 37 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "_comment": "To apply prettier config to Webstorm https://intellij-support.jetbrains.com/hc/en-us/community/posts/360002745119-How-to-have-Reformat-Code-feature-behave-exactly-like-Prettier-", 3 | "arrowParens": "always", 4 | "bracketSpacing": true, 5 | "jsxBracketSameLine": true, 6 | "printWidth": 80, 7 | "tabWidth": 2, 8 | "proseWrap": "never", 9 | "singleQuote": true, 10 | "trailingComma": "es5", 11 | "endOfLine": "lf", 12 | "semi": true 13 | } 14 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | AgileTs has adopted a Code of Conduct that we expect project participants to follow. 4 | Please read the [read the full text](https://code.fb.com/codeofconduct/) so that you can understand what actions will and will not be tolerated. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 bennodev19 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /benchmark/.env: -------------------------------------------------------------------------------- 1 | DEV=false 2 | -------------------------------------------------------------------------------- /benchmark/benchmarks/react/computed/bench/agilets/autoTracking.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | import { 4 | createComputed, 5 | createState, 6 | logCodeManager, 7 | shared, 8 | } from '@agile-ts/core'; 9 | import reactIntegration, { useAgile } from '@agile-ts/react'; 10 | 11 | logCodeManager.allowLogging = false; 12 | shared.integrate(reactIntegration); 13 | 14 | const COUNT = createState(0); 15 | const COMPUTED_COUNT = createComputed(() => { 16 | return COUNT.value * 5; 17 | }); 18 | 19 | const CountView = () => { 20 | const count = useAgile(COUNT); 21 | return

COUNT.set((state) => state + 1)}>{count}

; 22 | }; 23 | 24 | const ComputedCountView = () => { 25 | const computedCount = useAgile(COMPUTED_COUNT); 26 | return

{computedCount}

; 27 | }; 28 | 29 | const App = () => { 30 | return ( 31 |
32 | 33 | 34 |
35 | ); 36 | }; 37 | 38 | export default function (target: HTMLElement) { 39 | ReactDom.render(, target); 40 | } 41 | -------------------------------------------------------------------------------- /benchmark/benchmarks/react/computed/bench/agilets/hardCoded.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | import { 4 | createComputed, 5 | createState, 6 | logCodeManager, 7 | shared, 8 | } from '@agile-ts/core'; 9 | import reactIntegration, { useAgile } from '@agile-ts/react'; 10 | 11 | logCodeManager.allowLogging = false; 12 | shared.integrate(reactIntegration); 13 | 14 | const COUNT = createState(0); 15 | const COMPUTED_COUNT = createComputed( 16 | () => { 17 | return COUNT.value * 5; 18 | }, 19 | { autodetect: false, computedDeps: [COUNT] } 20 | ); 21 | 22 | const CountView = () => { 23 | const count = useAgile(COUNT); 24 | return

COUNT.set((state) => state + 1)}>{count}

; 25 | }; 26 | 27 | const ComputedCountView = () => { 28 | const computedCount = useAgile(COMPUTED_COUNT); 29 | return

{computedCount}

; 30 | }; 31 | 32 | const App = () => { 33 | return ( 34 |
35 | 36 | 37 |
38 | ); 39 | }; 40 | 41 | export default function (target: HTMLElement) { 42 | ReactDom.render(, target); 43 | } 44 | -------------------------------------------------------------------------------- /benchmark/benchmarks/react/computed/bench/jotai.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | import { atom, useAtom } from 'jotai'; 4 | 5 | const countAtom = atom(0); 6 | const computedCountAtom = atom((get) => get(countAtom) * 5); 7 | 8 | const CountView = () => { 9 | const [count, setCount] = useAtom(countAtom); 10 | return

setCount((v) => v + 1)}>{count}

; 11 | }; 12 | 13 | const ComputedCountView = () => { 14 | const [computedCount] = useAtom(computedCountAtom); 15 | return

{computedCount}

; 16 | }; 17 | 18 | const App = () => { 19 | return ( 20 |
21 | 22 | 23 |
24 | ); 25 | }; 26 | 27 | export default function (target: HTMLElement) { 28 | ReactDom.render(, target); 29 | } 30 | -------------------------------------------------------------------------------- /benchmark/benchmarks/react/computed/bench/nanostores.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | import { createDerived, createStore, getValue } from 'nanostores'; 4 | import { useStore } from 'nanostores/react'; 5 | 6 | const countStore = createStore(() => { 7 | countStore.set(0); 8 | }); 9 | const computedStore = createDerived(countStore, (count) => { 10 | return count * 5; 11 | }); 12 | 13 | const CountView = () => { 14 | const count = useStore(countStore); 15 | return ( 16 |

countStore.set(getValue(countStore) + 1)}>{count}

17 | ); 18 | }; 19 | 20 | const ComputedCountView = () => { 21 | const computedCount = useStore(computedStore); 22 | return

{computedCount}

; 23 | }; 24 | 25 | const App = () => { 26 | return ( 27 |
28 | 29 | 30 |
31 | ); 32 | }; 33 | 34 | export default function (target: HTMLElement) { 35 | ReactDom.render(, target); 36 | } 37 | -------------------------------------------------------------------------------- /benchmark/benchmarks/react/counter/bench/agilets.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | import { createState, shared, logCodeManager } from '@agile-ts/core'; 4 | import reactIntegration, { useAgile } from '@agile-ts/react'; 5 | 6 | logCodeManager.allowLogging = false; 7 | shared.integrate(reactIntegration); 8 | 9 | const COUNT = createState(0); 10 | 11 | const App = () => { 12 | const count = useAgile(COUNT); 13 | return

COUNT.set((state) => state + 1)}>{count}

; 14 | }; 15 | 16 | export default function (target: HTMLElement) { 17 | ReactDom.render(, target); 18 | } 19 | -------------------------------------------------------------------------------- /benchmark/benchmarks/react/counter/bench/hookstate.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | import { createState, useHookstate } from '@hookstate/core'; 4 | 5 | const counter = createState(0); 6 | 7 | const App = () => { 8 | const state = useHookstate(counter); 9 | return

state.set((v) => v + 1)}>{state.get()}

; 10 | }; 11 | 12 | export default function (target: HTMLElement) { 13 | ReactDom.render(, target); 14 | } 15 | -------------------------------------------------------------------------------- /benchmark/benchmarks/react/counter/bench/jotai.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | import { atom, useAtom } from 'jotai'; 4 | 5 | const countAtom = atom(0); 6 | 7 | const App = () => { 8 | const [count, setCount] = useAtom(countAtom); 9 | return

setCount((v) => v + 1)}>{count}

; 10 | }; 11 | 12 | export default function (target: HTMLElement) { 13 | ReactDom.render(, target); 14 | } 15 | -------------------------------------------------------------------------------- /benchmark/benchmarks/react/counter/bench/mobx.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | import { action, observable } from 'mobx'; 4 | import { observer } from 'mobx-react'; 5 | 6 | const appState = observable({ 7 | count: 0, 8 | increment: action(function () { 9 | appState.count += 1; 10 | }), 11 | }); 12 | 13 | const App = observer(() => { 14 | return

{appState.count}

; 15 | }); 16 | 17 | export default function (target: HTMLElement) { 18 | ReactDom.render(, target); 19 | } 20 | -------------------------------------------------------------------------------- /benchmark/benchmarks/react/counter/bench/nanostores.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | import { createStore, getValue } from 'nanostores'; 4 | import { useStore } from 'nanostores/react'; 5 | 6 | const countStore = createStore(() => { 7 | countStore.set(0); 8 | }); 9 | 10 | const App = () => { 11 | const count = useStore(countStore); 12 | return ( 13 |

countStore.set(getValue(countStore) + 1)}>{count}

14 | ); 15 | }; 16 | 17 | export default function (target: HTMLElement) { 18 | ReactDom.render(, target); 19 | } 20 | -------------------------------------------------------------------------------- /benchmark/benchmarks/react/counter/bench/pulsejs.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | import { state } from '@pulsejs/core'; 4 | import { usePulse } from '@pulsejs/react'; 5 | 6 | const COUNT = state(0); 7 | 8 | const App = () => { 9 | const count = usePulse(COUNT); 10 | return

COUNT.set((state) => state + 1)}>{count}

; 11 | }; 12 | 13 | export default function (target: HTMLElement) { 14 | ReactDom.render(, target); 15 | } 16 | -------------------------------------------------------------------------------- /benchmark/benchmarks/react/counter/bench/recoil.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | import { atom, RecoilRoot, useRecoilState } from 'recoil'; 4 | 5 | const counterState = atom({ 6 | key: 'counterState', 7 | default: 0, 8 | }); 9 | 10 | const App = () => { 11 | const [count, setCount] = useRecoilState(counterState); 12 | return

setCount((v) => v + 1)}>{count}

; 13 | }; 14 | 15 | export default function (target: HTMLElement) { 16 | ReactDom.render( 17 | 18 | 19 | , 20 | target 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /benchmark/benchmarks/react/counter/bench/redux-toolkit.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | import { configureStore, createSlice } from '@reduxjs/toolkit'; 4 | import { Provider, useDispatch, useSelector } from 'react-redux'; 5 | 6 | const counterSlice = createSlice({ 7 | name: 'counter', 8 | initialState: { 9 | count: 0, 10 | }, 11 | reducers: { 12 | increment: (state) => { 13 | state.count += 1; 14 | }, 15 | }, 16 | }); 17 | 18 | const store = configureStore({ 19 | reducer: { 20 | counter: counterSlice.reducer, 21 | }, 22 | }); 23 | 24 | const App = () => { 25 | const count = useSelector((state: any) => state.counter.count); 26 | const dispatch = useDispatch(); 27 | 28 | return ( 29 |

dispatch(counterSlice.actions.increment())}>{count}

30 | ); 31 | }; 32 | 33 | export default function (target: HTMLElement) { 34 | ReactDom.render( 35 | 36 | 37 | , 38 | target 39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /benchmark/benchmarks/react/counter/bench/redux.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | import { combineReducers, createStore } from 'redux'; 4 | import { Provider, useDispatch, useSelector } from 'react-redux'; 5 | 6 | const increment = () => { 7 | return { 8 | type: 'INCREMENT', 9 | }; 10 | }; 11 | 12 | const counter = (state = 0, action: any) => { 13 | switch (action.type) { 14 | case 'INCREMENT': 15 | return state + 1; 16 | default: 17 | return state; 18 | } 19 | }; 20 | 21 | const rootReducer = combineReducers({ 22 | counter, 23 | }); 24 | 25 | const store = createStore(rootReducer); 26 | 27 | const App = () => { 28 | const count = useSelector((state: any) => state.counter); 29 | const dispatch = useDispatch(); 30 | 31 | return

dispatch(increment())}>{count}

; 32 | }; 33 | 34 | export default function (target: HTMLElement) { 35 | ReactDom.render( 36 | 37 | 38 | , 39 | target 40 | ); 41 | } 42 | -------------------------------------------------------------------------------- /benchmark/benchmarks/react/counter/bench/valtio.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | import { proxy, useSnapshot } from 'valtio'; 4 | 5 | const state = proxy({ count: 0 }); 6 | 7 | function App() { 8 | const snapshot = useSnapshot(state, { sync: true }); 9 | return

state.count++}>{snapshot.count}

; 10 | } 11 | 12 | export default function (target: HTMLElement) { 13 | ReactDom.render(, target); 14 | } 15 | -------------------------------------------------------------------------------- /benchmark/benchmarks/react/counter/bench/zustand.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | import create from 'zustand'; 4 | 5 | const useStore = create((set) => ({ 6 | count: 0, 7 | increment: () => set((state) => ({ count: state.count + 1 })), 8 | })); 9 | 10 | const App = () => { 11 | const count = useStore((state) => state.count); 12 | const increment = useStore((state) => state.increment); 13 | 14 | return

{count}

; 15 | }; 16 | 17 | export default function (target: HTMLElement) { 18 | ReactDom.render(, target); 19 | } 20 | -------------------------------------------------------------------------------- /benchmark/benchmarks/typescript/cloneDeep/bench/lodash.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import _ from 'lodash'; 3 | 4 | export function cloneDeep(value: T): T { 5 | return _.cloneDeep(value); 6 | } 7 | -------------------------------------------------------------------------------- /benchmark/benchmarks/typescript/cloneDeep/bench/looper.ts: -------------------------------------------------------------------------------- 1 | export function cloneDeep(value: T): T { 2 | // Extra checking 'value == null' because 'typeof null === object' 3 | if (value == null || typeof value !== 'object') return value; 4 | 5 | // Ignore everything that is no object or array but has the type of an object (e.g. classes) 6 | const valConstructorName = 7 | Object.getPrototypeOf(value).constructor.name.toLowerCase(); 8 | if (valConstructorName !== 'object' && valConstructorName !== 'array') 9 | return value; 10 | 11 | let temp; 12 | const newObject: any = Array.isArray(value) ? [] : {}; 13 | for (const property in value) { 14 | temp = value[property]; 15 | newObject[property] = cloneDeep(temp); 16 | } 17 | return newObject as T; 18 | } 19 | -------------------------------------------------------------------------------- /benchmark/benchmarks/typescript/cloneDeep/bench/stringify.ts: -------------------------------------------------------------------------------- 1 | export function cloneDeep(value: T): T { 2 | return JSON.parse(JSON.stringify(value)); 3 | } 4 | -------------------------------------------------------------------------------- /benchmark/benchmarks/typescript/defineConfig/bench/referencer.ts: -------------------------------------------------------------------------------- 1 | export function defineConfig( 2 | config: any, 3 | defaults: any, 4 | overwriteUndefinedProperties?: boolean 5 | ): void { 6 | if (overwriteUndefinedProperties === undefined) 7 | overwriteUndefinedProperties = true; 8 | 9 | for (const defaultKey in defaults) { 10 | if ( 11 | !Object.prototype.hasOwnProperty.call(config, defaultKey) || 12 | (overwriteUndefinedProperties && config[defaultKey] === undefined) 13 | ) 14 | config[defaultKey] = defaults[defaultKey]; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /benchmark/benchmarks/typescript/defineConfig/bench/spreadReferencer.ts: -------------------------------------------------------------------------------- 1 | export function defineConfig( 2 | config: any, 3 | defaults: any, 4 | overwriteUndefinedProperties?: boolean 5 | ): any { 6 | if (overwriteUndefinedProperties === undefined) 7 | overwriteUndefinedProperties = true; 8 | 9 | const shallowCopiedConfig = { ...config }; 10 | 11 | for (const defaultKey in defaults) { 12 | if ( 13 | !Object.prototype.hasOwnProperty.call(shallowCopiedConfig, defaultKey) || 14 | (overwriteUndefinedProperties && 15 | shallowCopiedConfig[defaultKey] === undefined) 16 | ) 17 | shallowCopiedConfig[defaultKey] = defaults[defaultKey]; 18 | } 19 | 20 | return shallowCopiedConfig; 21 | } 22 | -------------------------------------------------------------------------------- /benchmark/benchmarks/typescript/defineConfig/bench/spreader.ts: -------------------------------------------------------------------------------- 1 | export function defineConfig( 2 | config: any, 3 | defaults: any, 4 | overwriteUndefinedProperties?: boolean 5 | ): any { 6 | if (overwriteUndefinedProperties === undefined) 7 | overwriteUndefinedProperties = true; 8 | 9 | if (overwriteUndefinedProperties) { 10 | const finalConfig = { ...defaults, ...config }; 11 | for (const key in finalConfig) 12 | if (finalConfig[key] === undefined) finalConfig[key] = defaults[key]; 13 | return finalConfig; 14 | } 15 | 16 | return { ...defaults, ...config }; 17 | } 18 | -------------------------------------------------------------------------------- /benchmark/lodash.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | 3 | // Benchmark.js requires lodash globally 4 | window._ = _; 5 | -------------------------------------------------------------------------------- /benchmark/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Benchmark 6 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /benchmark/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "resolveJsonModule": true, 18 | "isolatedModules": true, 19 | "noEmit": true, 20 | "jsx": "react" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | Here you find some examples related to AgileTs. 4 | We have tried to make them as simple as possible so that you get the most out of them. 5 | Feel free to clone and test them to get a better understanding of AgileTs. Have fun. 6 | 7 | The Examples are structured framework specific. So you can find React related examples in the `react` folder. 8 | Currently, we have examples for these frameworks: 9 | 10 | - [react](./react) 11 | - [react-native](./react-native) 12 | 13 | To find out more checkout our [documentation](https://agile-ts.org/examples). -------------------------------------------------------------------------------- /examples/nextjs/develop/clock/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["next", "next/core-web-vitals"] 3 | } 4 | -------------------------------------------------------------------------------- /examples/nextjs/develop/clock/.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 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | # vercel 34 | .vercel 35 | -------------------------------------------------------------------------------- /examples/nextjs/develop/clock/components/Clock.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useAgile } from '@agile-ts/react'; 3 | import { LAST_UPDATED_TIMESTAMP, LIGHT } from '../src/core'; 4 | 5 | const formatTime = (timestamp: number) => { 6 | // cut off except hh:mm:ss 7 | return new Date(timestamp).toJSON().slice(11, 19); 8 | }; 9 | 10 | const Clock = () => { 11 | const [lastUpdatedTimestamp, light] = useAgile([ 12 | LAST_UPDATED_TIMESTAMP, 13 | LIGHT, 14 | ]); 15 | 16 | return ( 17 |
18 | {formatTime(lastUpdatedTimestamp)} 19 | 31 |
32 | ); 33 | }; 34 | 35 | export default Clock; 36 | -------------------------------------------------------------------------------- /examples/nextjs/develop/clock/components/Counter.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useAgile } from '@agile-ts/react'; 3 | import { 4 | COUNTER, 5 | decrementCount, 6 | incrementCount, 7 | resetCount, 8 | } from '../src/core'; 9 | 10 | const Counter = () => { 11 | const count = useAgile(COUNTER); 12 | 13 | return ( 14 |
15 |

16 | Count: {count} 17 |

18 | 19 | 20 | 21 |
22 | ); 23 | }; 24 | 25 | export default Counter; 26 | -------------------------------------------------------------------------------- /examples/nextjs/develop/clock/components/Nav.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Link from 'next/link'; 3 | 4 | const Nav = () => { 5 | return ( 6 | 24 | ); 25 | }; 26 | 27 | export default Nav; 28 | -------------------------------------------------------------------------------- /examples/nextjs/develop/clock/components/Page.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import useInterval from '../src/useInterval'; 3 | import Nav from './Nav'; 4 | import Clock from './Clock'; 5 | import Counter from './Counter'; 6 | import { tick } from '../src/core'; 7 | 8 | const Page = () => { 9 | // Tick the time every second 10 | useInterval(() => { 11 | tick(Date.now(), true); 12 | }, 1000); 13 | 14 | return ( 15 | <> 16 |