├── .eslintrc.js ├── .github └── workflows │ └── deploy.yml ├── .gitignore ├── .graphqlrc.yml ├── .husky └── pre-commit ├── .npmrc ├── .prettierignore ├── .prettierrc ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── __tests__ ├── MyReactLib.html ├── grid.js ├── list.html ├── testAntd.html ├── testArray.html ├── testArray_2.html ├── testBabel.html ├── testChildren.html ├── testClass.html ├── testClassComponent.html ├── testContext.html ├── testDomUpdate.html ├── testEffect.html ├── testError.html ├── testEvent.html ├── testEvent_2.html ├── testEvent_3.html ├── testFiber.html ├── testFocus.html ├── testHook.html ├── testInput.html ├── testKeepLive.html ├── testKeepLivePortal.html ├── testKey.html ├── testKeyUpdate.html ├── testLazy.html ├── testLoop.html ├── testMemary.html ├── testMemo.html ├── testPortal.html ├── testReactGridLayout.html ├── testReactSlider.html ├── testReactive.html ├── testReactiveComponent.html ├── testRedux.html ├── testReduxToolKit.html ├── testRef.html ├── testRef_2.html ├── testRef_3.html ├── testRef_4.html ├── testRender.html ├── testRenderForTask.html ├── testSSR.html ├── testSSRContent.html ├── testSignal.html ├── testStyle.html ├── testSuspense.html ├── testSuspenseHydrate.html ├── testSuspense_2.html ├── testToggle.html ├── testToggleRender.html ├── testTransition.html ├── testUnmount.html ├── testUpdate.html ├── testUpdate_2.html ├── testUpdate_3.html ├── testUpdate_4.html ├── testUpdate_5.html ├── testUpdate_6.html ├── testUseDeferredValue.html ├── testUseId.html ├── testZustand.html ├── textUnmount_2.html ├── todoMVC.html └── useStore.html ├── bundle ├── babel.min.js ├── react-dom.18.development.js ├── react-dom.development.js ├── react.18.development.js ├── react.development.js ├── reactReduxBundle.js ├── reduxBundle.js ├── reduxToolKitBundle.js ├── thunkBundle.js └── zustandBundle.js ├── commit.mjs ├── global.d.ts ├── package.json ├── packages ├── myreact-dom │ ├── LICENSE │ ├── client.js │ ├── index.js │ ├── package.json │ ├── readme.md │ ├── server.browser.js │ ├── server.js │ ├── server.node.js │ ├── src │ │ ├── client │ │ │ ├── api │ │ │ │ ├── append │ │ │ │ │ └── index.ts │ │ │ │ ├── clear │ │ │ │ │ ├── feature.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── create │ │ │ │ │ ├── feature.ts │ │ │ │ │ ├── getHydrateDom.ts │ │ │ │ │ ├── hydrateCreate.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── nativeCreate.ts │ │ │ │ ├── fallback │ │ │ │ │ ├── feature.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── helper │ │ │ │ │ ├── attr │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── namespace.ts │ │ │ │ │ │ ├── setAttr.ts │ │ │ │ │ │ ├── setInnerHtml.ts │ │ │ │ │ │ └── setText.ts │ │ │ │ │ ├── control │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── input.ts │ │ │ │ │ │ ├── select.ts │ │ │ │ │ │ └── textarea.ts │ │ │ │ │ ├── event │ │ │ │ │ │ ├── addEvent.ts │ │ │ │ │ │ ├── getEventName.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── removeEvent.ts │ │ │ │ │ │ └── wrapper.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── style │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── setStyle.ts │ │ │ │ ├── index.ts │ │ │ │ ├── position │ │ │ │ │ ├── append.ts │ │ │ │ │ ├── feature.ts │ │ │ │ │ ├── getInsertBeforeDom.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── insertBefore.ts │ │ │ │ └── update │ │ │ │ │ ├── control.ts │ │ │ │ │ ├── feature.ts │ │ │ │ │ ├── hydrateUpdate.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── nativeUpdate.ts │ │ │ │ │ └── tool.ts │ │ │ ├── dispatchMount │ │ │ │ ├── feature.ts │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── mount │ │ │ │ ├── createRoot.ts │ │ │ │ ├── hydrate.ts │ │ │ │ ├── hydrateRoot.ts │ │ │ │ ├── index.ts │ │ │ │ └── render.ts │ │ │ ├── renderDispatch │ │ │ │ ├── dispatch.ts │ │ │ │ ├── index.ts │ │ │ │ └── instance.ts │ │ │ └── tools │ │ │ │ ├── createPortal.ts │ │ │ │ ├── debug.ts │ │ │ │ ├── findDOMNode.ts │ │ │ │ ├── hmr.ts │ │ │ │ ├── index.ts │ │ │ │ ├── ref.ts │ │ │ │ └── unmountComponentAtNode.ts │ │ ├── global.d.ts │ │ ├── index.ts │ │ ├── noop │ │ │ ├── mount │ │ │ │ ├── index.ts │ │ │ │ └── render.ts │ │ │ └── renderDispatch │ │ │ │ ├── index.ts │ │ │ │ ├── instance.ts │ │ │ │ └── unmount.ts │ │ ├── server │ │ │ ├── api │ │ │ │ ├── append.ts │ │ │ │ ├── create.ts │ │ │ │ ├── index.ts │ │ │ │ ├── native │ │ │ │ │ ├── comment.ts │ │ │ │ │ ├── container.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── plain.ts │ │ │ │ │ └── text.ts │ │ │ │ └── update.ts │ │ │ ├── index.ts │ │ │ ├── mount │ │ │ │ ├── index.ts │ │ │ │ ├── renderToNodeStream.ts │ │ │ │ ├── renderToPipeableStream.ts │ │ │ │ ├── renderToReadableStream.ts │ │ │ │ ├── renderToStaticMarkup.ts │ │ │ │ ├── renderToStaticNodeStream.ts │ │ │ │ └── renderToString.ts │ │ │ └── renderDispatch │ │ │ │ ├── generateBootstrap.ts │ │ │ │ ├── index.ts │ │ │ │ ├── serverDomDispatch.ts │ │ │ │ ├── serverStreamDispatch.ts │ │ │ │ └── unmount.ts │ │ └── shared │ │ │ ├── comment.ts │ │ │ ├── dev.ts │ │ │ ├── dom.ts │ │ │ ├── elementAttrs.ts │ │ │ ├── elementMap.ts │ │ │ ├── elementStyle.ts │ │ │ ├── elementTag.ts │ │ │ ├── env.ts │ │ │ ├── escapeHtml.ts │ │ │ ├── getFiberWithDom.ts │ │ │ ├── head.ts │ │ │ ├── index.ts │ │ │ ├── init.ts │ │ │ ├── kebabCase.ts │ │ │ ├── log.ts │ │ │ ├── promise.ts │ │ │ ├── render.ts │ │ │ ├── shouldPause.ts │ │ │ ├── tools.ts │ │ │ ├── validate.ts │ │ │ ├── validateDomNesting.ts │ │ │ ├── validateProps.ts │ │ │ ├── validateTag.ts │ │ │ └── version.ts │ └── tsconfig.json ├── myreact-jsx │ ├── LICENSE │ ├── index.js │ ├── jsx-dev-runtime.d.ts │ ├── jsx-dev-runtime.js │ ├── jsx-runtime.d.ts │ ├── jsx-runtime.js │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── check.ts │ │ ├── global.d.ts │ │ ├── index.ts │ │ └── instance.ts │ └── tsconfig.json ├── myreact-reactivity │ ├── LICENSE │ ├── index.d.ts │ ├── index.js │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── api │ │ │ ├── computed.ts │ │ │ ├── create.ts │ │ │ ├── createRef.ts │ │ │ ├── effect.ts │ │ │ ├── handler.ts │ │ │ ├── index.ts │ │ │ ├── reactive.ts │ │ │ ├── ref.ts │ │ │ ├── symbol.ts │ │ │ └── watch.ts │ │ ├── global.d.ts │ │ ├── index.ts │ │ ├── reactive │ │ │ ├── feature.ts │ │ │ ├── hook.ts │ │ │ └── index.ts │ │ └── share │ │ │ ├── globalMap.ts │ │ │ └── index.ts │ └── tsconfig.json ├── myreact-reconciler-compact │ ├── LICENSE │ ├── index.d.ts │ ├── index.js │ ├── package.json │ ├── src │ │ ├── api │ │ │ ├── append.ts │ │ │ ├── create.ts │ │ │ ├── index.ts │ │ │ ├── position.ts │ │ │ ├── ref.ts │ │ │ ├── remove.ts │ │ │ └── update.ts │ │ ├── devtool.ts │ │ ├── dispatch.ts │ │ ├── dispatchFiber.ts │ │ ├── dispatchMap.ts │ │ ├── dispatchMount.ts │ │ ├── feature.ts │ │ ├── global.d.ts │ │ ├── hmr.ts │ │ ├── index.ts │ │ ├── polyfill.ts │ │ ├── portal.ts │ │ └── scheduler.ts │ └── tsconfig.json ├── myreact-reconciler │ ├── LICENSE │ ├── index.d.ts │ ├── index.js │ ├── package.json │ ├── src │ │ ├── dispatchContext │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── dispatchEffect │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── dispatchErrorBoundaries │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── dispatchFiber │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── dispatchMount │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── dispatchScope │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── dispatchStrict │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── dispatchSuspense │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── dispatchUnmount │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── dispatchUpdate │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── global.d.ts │ │ ├── index.ts │ │ ├── processClass │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── processContext │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── processFunction │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── processHook │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── processLazy │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── processPromise │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── processQueue │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── processState │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── processSuspense │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── renderDispatch │ │ │ ├── event.ts │ │ │ ├── index.ts │ │ │ ├── instance.ts │ │ │ └── interface.ts │ │ ├── renderMount │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── renderNextWork │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── renderUnmount │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── renderUpdate │ │ │ ├── feature.ts │ │ │ ├── index.ts │ │ │ ├── schedule.ts │ │ │ └── trigger.ts │ │ ├── runtimeFiber │ │ │ ├── check.ts │ │ │ ├── clear.ts │ │ │ ├── create.ts │ │ │ ├── hmr.ts │ │ │ ├── index.ts │ │ │ ├── initial.ts │ │ │ ├── instance.ts │ │ │ ├── interface.ts │ │ │ ├── trigger.ts │ │ │ ├── unmount.ts │ │ │ └── update.ts │ │ ├── runtimeGenerate │ │ │ ├── generate.ts │ │ │ ├── index.ts │ │ │ ├── instance.ts │ │ │ └── invoke.ts │ │ ├── runtimeHook │ │ │ ├── check.ts │ │ │ ├── create.ts │ │ │ ├── effect.ts │ │ │ ├── index.ts │ │ │ ├── instance.ts │ │ │ ├── signal.ts │ │ │ ├── unmount.ts │ │ │ └── update.ts │ │ ├── runtimeMount │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── runtimeScope │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ ├── runtimeUpdate │ │ │ ├── feature.ts │ │ │ └── index.ts │ │ └── share │ │ │ ├── debug.ts │ │ │ ├── elementType.ts │ │ │ ├── env.ts │ │ │ ├── fiberToList.ts │ │ │ ├── fiberType.ts │ │ │ ├── hmr.ts │ │ │ ├── index.ts │ │ │ ├── isSameType.ts │ │ │ ├── map.ts │ │ │ ├── refresh.ts │ │ │ ├── safeCall.ts │ │ │ ├── scheduler.ts │ │ │ └── sync.ts │ └── tsconfig.json ├── myreact-refresh-tools │ ├── RefreshWebpackPlugin.d.ts │ ├── RefreshWebpackPlugin.js │ ├── loader.d.ts │ ├── loader.js │ ├── package.json │ ├── readme.md │ ├── runtime.d.ts │ ├── runtime.js │ ├── src │ │ ├── internal │ │ │ ├── RefreshModule.runtime.ts │ │ │ └── helpers.ts │ │ ├── loader.ts │ │ ├── runtime.ts │ │ └── webpackPlugin.ts │ ├── tsconfig.json │ └── withNext.js ├── myreact-refresh │ ├── LICENSE │ ├── babel.js │ ├── package.json │ ├── readme.md │ ├── runtime.d.ts │ ├── runtime.js │ ├── src │ │ ├── RefreshBabelPlugin.ts │ │ ├── RefreshRuntime.ts │ │ └── global.d.ts │ └── tsconfig.json ├── myreact-rspack │ ├── .gitignore │ ├── client │ │ ├── errorOverlayEntry.js │ │ ├── overlay │ │ │ ├── components │ │ │ │ ├── CompileErrorTrace.js │ │ │ │ ├── PageHeader.js │ │ │ │ ├── RuntimeErrorFooter.js │ │ │ │ ├── RuntimeErrorHeader.js │ │ │ │ ├── RuntimeErrorStack.js │ │ │ │ └── Spacer.js │ │ │ ├── containers │ │ │ │ ├── CompileErrorContainer.js │ │ │ │ └── RuntimeErrorContainer.js │ │ │ ├── index.js │ │ │ ├── theme.js │ │ │ └── utils.js │ │ ├── reactRefresh.js │ │ ├── reactRefreshEntry.js │ │ ├── refreshUtils.js │ │ └── utils │ │ │ ├── ansi-html.js │ │ │ ├── errorEventHandlers.js │ │ │ ├── formatWebpackErrors.js │ │ │ └── retry.js │ ├── index.d.ts │ ├── index.js │ ├── overlay.js │ ├── package.json │ ├── react-refresh-entry.js │ ├── react-refresh.js │ ├── readme.md │ ├── src │ │ ├── global.d.ts │ │ ├── index.ts │ │ ├── options.ts │ │ ├── paths.ts │ │ ├── sockets │ │ │ ├── WDSSocket.ts │ │ │ ├── WHMEventSource.ts │ │ │ └── utils │ │ │ │ ├── getCurrentScriptSource.ts │ │ │ │ ├── getSocketUrlParts.ts │ │ │ │ ├── getUrlFromParts.ts │ │ │ │ └── getWDSMetadata.ts │ │ └── utils │ │ │ ├── getAdditionalEntries.ts │ │ │ ├── getIntegrationEntry.ts │ │ │ └── getSocketIntegration.ts │ ├── tsconfig.build.json │ └── tsconfig.json ├── myreact-shared │ ├── LICENSE │ ├── index.d.ts │ ├── index.js │ ├── package.json │ ├── src │ │ ├── array.ts │ │ ├── bit.ts │ │ ├── global.d.ts │ │ ├── index.ts │ │ ├── isEquals.ts │ │ ├── listTree.ts │ │ ├── once.ts │ │ ├── symbol │ │ │ ├── fiberPatch.ts │ │ │ ├── fiberState.ts │ │ │ ├── hookType.ts │ │ │ ├── index.ts │ │ │ ├── instanceEffect.ts │ │ │ └── queueType.ts │ │ ├── tools.ts │ │ ├── type.ts │ │ └── version.ts │ └── tsconfig.json ├── myreact-terminal │ ├── LICENSE │ ├── index.d.ts │ ├── index.mjs │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── colorize.ts │ │ ├── components │ │ │ ├── App.tsx │ │ │ ├── AppContext.ts │ │ │ ├── Box.tsx │ │ │ ├── ErrorOverview.tsx │ │ │ ├── FocusContext.ts │ │ │ ├── Newline.tsx │ │ │ ├── Spacer.tsx │ │ │ ├── Static.tsx │ │ │ ├── StderrContext.ts │ │ │ ├── StdinContext.ts │ │ │ ├── StdoutContext.ts │ │ │ ├── Text.tsx │ │ │ └── Transform.tsx │ │ ├── dom.ts │ │ ├── get-max-width.ts │ │ ├── global.d.ts │ │ ├── hooks │ │ │ ├── use-app.ts │ │ │ ├── use-focus-manager.ts │ │ │ ├── use-focus.ts │ │ │ ├── use-input.ts │ │ │ ├── use-stderr.ts │ │ │ ├── use-stdin.ts │ │ │ └── use-stdout.ts │ │ ├── index.ts │ │ ├── ink.tsx │ │ ├── instances.ts │ │ ├── log-update.ts │ │ ├── measure-element.ts │ │ ├── measure-text.ts │ │ ├── output.ts │ │ ├── parse-keypress.ts │ │ ├── reconciler.ts │ │ ├── render-border.ts │ │ ├── render-node-to-output.ts │ │ ├── render.ts │ │ ├── renderer.ts │ │ ├── squash-text-nodes.ts │ │ ├── styles.ts │ │ └── wrap-text.ts │ └── tsconfig.json ├── myreact-three-fiber │ ├── LICENSE │ ├── index.d.ts │ ├── index.mjs │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── core │ │ │ ├── events.ts │ │ │ ├── hooks.tsx │ │ │ ├── index.tsx │ │ │ ├── its-fine.tsx │ │ │ ├── loop.ts │ │ │ ├── reconciler.tsx │ │ │ ├── renderer.tsx │ │ │ ├── store.ts │ │ │ └── utils.tsx │ │ ├── index.tsx │ │ ├── three-types.ts │ │ └── web │ │ │ ├── Canvas.tsx │ │ │ └── events.ts │ └── tsconfig.json ├── myreact-vite │ ├── index.js │ ├── package.json │ ├── readme.md │ ├── refreshUtils.js │ ├── src │ │ ├── fast-refresh.ts │ │ ├── index.ts │ │ └── refreshUtils.ts │ └── tsconfig.json └── myreact │ ├── LICENSE │ ├── index.js │ ├── jsx-dev-runtime.js │ ├── jsx-runtime.js │ ├── package.json │ ├── readme.md │ ├── src │ ├── children │ │ ├── feature.ts │ │ ├── index.ts │ │ └── tool.ts │ ├── component │ │ ├── index.ts │ │ └── instance.ts │ ├── element │ │ ├── feature.ts │ │ ├── index.ts │ │ ├── instance.ts │ │ └── tool.ts │ ├── global.d.ts │ ├── hook │ │ ├── feature.ts │ │ └── index.ts │ ├── index.ts │ ├── internal │ │ ├── index.ts │ │ └── instance.ts │ ├── renderFiber │ │ ├── index.ts │ │ └── interface.ts │ ├── renderHook │ │ ├── index.ts │ │ └── interface.ts │ ├── renderQueue │ │ ├── index.ts │ │ └── interface.ts │ ├── renderScheduler │ │ ├── feature.ts │ │ ├── index.ts │ │ └── interface.ts │ └── share │ │ ├── cache.ts │ │ ├── createRef.ts │ │ ├── dispatch.ts │ │ ├── env.ts │ │ ├── hook.ts │ │ ├── index.ts │ │ ├── task.ts │ │ └── transition.ts │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── scripts ├── cleanType.ts ├── release.ts ├── rollupBuild.ts ├── rollupTerminal.ts ├── rollupWatch.ts └── tsconfig.json ├── site ├── graphql │ ├── .eslintrc.js │ ├── codegen.yaml │ ├── env.d.ts │ ├── index.js │ ├── package.json │ ├── schema.graphql │ ├── src │ │ ├── apollo │ │ │ ├── cache.ts │ │ │ ├── client.ts │ │ │ ├── index.ts │ │ │ └── links.ts │ │ ├── document │ │ │ ├── auth.graphql │ │ │ ├── blog.graphql │ │ │ ├── repo.graphql │ │ │ └── star.graphql │ │ ├── generated.ts │ │ ├── index.ts │ │ └── schema.ts │ └── tsconfig.json ├── lib │ ├── build │ │ ├── bootStrap.js │ │ ├── getAllDeps.js │ │ ├── getCommonJSDeps.js │ │ ├── getFileContent.js │ │ ├── index.js │ │ └── writeFileContent.js │ ├── redux │ │ ├── log.js │ │ ├── reactRedux.js │ │ ├── redux.js │ │ ├── thunk.js │ │ └── toolkit.js │ └── zustand │ │ ├── index.js │ │ ├── instance.js │ │ └── react.js └── webpack │ ├── index.js │ ├── package.json │ ├── src │ ├── base │ │ ├── config │ │ │ ├── common.ts │ │ │ ├── externals.ts │ │ │ ├── index.ts │ │ │ ├── output.ts │ │ │ ├── plugins.ts │ │ │ └── statsConfig.ts │ │ ├── index.ts │ │ ├── plugin │ │ │ └── webpack-page-deps.ts │ │ ├── type.ts │ │ ├── utils │ │ │ ├── config.ts │ │ │ └── index.ts │ │ ├── webpack.base.config.ts │ │ ├── webpack.client.config.ts │ │ ├── webpack.config.ts │ │ └── webpack.server.config.ts │ ├── index.ts │ ├── react │ │ ├── config │ │ │ ├── devServer.ts │ │ │ ├── index.ts │ │ │ ├── optimization.ts │ │ │ ├── plugins.ts │ │ │ ├── resolve.ts │ │ │ └── rules.ts │ │ ├── index.ts │ │ └── type.ts │ └── safeParse.ts │ └── tsconfig.json ├── test.mjs ├── test ├── terminal │ ├── LICENSE │ ├── index.d.ts │ ├── index.mjs │ ├── package.json │ ├── src │ │ ├── border.tsx │ │ ├── count.tsx │ │ ├── dir.tsx │ │ ├── focus-id.tsx │ │ ├── focus.tsx │ │ ├── github.tsx │ │ ├── index.ts │ │ ├── input.tsx │ │ ├── justify-content.tsx │ │ ├── static.tsx │ │ ├── stderr.tsx │ │ ├── suspense.tsx │ │ └── table.tsx │ └── tsconfig.json └── three-fiber │ ├── index.html │ ├── package.json │ ├── public │ ├── favicon.ico │ └── vite.svg │ ├── src │ ├── App.css │ ├── App.tsx │ ├── assets │ │ └── react.svg │ ├── components │ │ ├── AutoDispose.tsx │ │ ├── ContextMenuOverride.tsx │ │ ├── MultiMaterial.tsx │ │ ├── MultiRender.tsx │ │ ├── Pointcloud.tsx │ │ ├── Reparenting.tsx │ │ ├── Simple.tsx │ │ └── SuspenseMaterial.tsx │ ├── index.css │ ├── main.tsx │ └── vite.d.ts │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── tsconfig.json └── ui ├── csr-example ├── ._root │ └── root │ │ ├── recover │ │ └── test.exe │ │ └── root │ │ ├── Snipaste.png │ │ ├── newFile.js │ │ └── newFile.txt ├── .env ├── .eslintrc.js ├── babel.config.js ├── build │ ├── scripts │ │ ├── build-prod.ts │ │ ├── compiler.ts │ │ ├── config.ts │ │ ├── entry-dev.ts │ │ ├── entry-prod.ts │ │ ├── log.ts │ │ ├── start-dev.ts │ │ ├── startDevServer.ts │ │ └── startServerWatch.ts │ └── tsconfig.json ├── global.d.ts ├── node │ ├── api.js │ ├── lib │ │ ├── copyFile.js │ │ ├── createFile.js │ │ ├── createFolder.js │ │ ├── deleteFile.js │ │ ├── deleteFolder.js │ │ ├── deleteItem.js │ │ ├── getFolder.js │ │ ├── moveItem.js │ │ ├── mv.js │ │ ├── readAbleStream.js │ │ ├── renameItem.js │ │ └── tools.js │ ├── server.js │ └── user ├── package.json ├── public │ ├── favicon.ico │ └── lib │ │ └── flexible.js ├── readme.md ├── src │ ├── client │ │ ├── App.js │ │ ├── component │ │ │ ├── bg │ │ │ │ └── index.js │ │ │ ├── dir │ │ │ │ ├── dir.css │ │ │ │ ├── dirContainer.js │ │ │ │ ├── echartsContainer │ │ │ │ │ ├── echartsContainer.js │ │ │ │ │ ├── echartsContainerBody.js │ │ │ │ │ ├── echartsContainerHead.js │ │ │ │ │ ├── echartsOptionBar.js │ │ │ │ │ └── echartsOptionPie.js │ │ │ │ ├── fileContainer │ │ │ │ │ ├── block │ │ │ │ │ │ ├── fileBlock.js │ │ │ │ │ │ ├── fileBlockBody.js │ │ │ │ │ │ ├── fileBlockDirItem.js │ │ │ │ │ │ ├── fileBlockFileItem.js │ │ │ │ │ │ └── fileBlockFileSubmitItem.js │ │ │ │ │ ├── fileContainer.js │ │ │ │ │ ├── fileContainerHead.js │ │ │ │ │ ├── fileContainerHeadAddDir.js │ │ │ │ │ ├── fileContainerHeadAddFile.js │ │ │ │ │ ├── fileContainerHeadDownloadFile.js │ │ │ │ │ ├── fileContainerHeadLeftBtn.js │ │ │ │ │ ├── fileContainerHeadRightBtn.js │ │ │ │ │ ├── fileContainerHeadSearchItem.js │ │ │ │ │ ├── fileContainerHeadSearchUl.js │ │ │ │ │ ├── fileContainerHeadUploadFile.js │ │ │ │ │ └── table │ │ │ │ │ │ ├── fileTable.js │ │ │ │ │ │ ├── fileTableBody.js │ │ │ │ │ │ ├── fileTableDirItem.js │ │ │ │ │ │ ├── fileTableDirItemRename.js │ │ │ │ │ │ ├── fileTableFileItem.js │ │ │ │ │ │ ├── fileTableFileItemCheck.js │ │ │ │ │ │ ├── fileTableFileItemRename.js │ │ │ │ │ │ └── fileTableFileItemSubmit.js │ │ │ │ └── menu │ │ │ │ │ ├── fileMenu.js │ │ │ │ │ ├── fileMenuCopyItem.js │ │ │ │ │ ├── fileMenuDeleteItem.js │ │ │ │ │ ├── fileMenuEditorItem.js │ │ │ │ │ ├── fileMenuMoveItem.js │ │ │ │ │ └── fileMenuRenameItem.js │ │ │ ├── file.js │ │ │ ├── file │ │ │ │ ├── codemirror │ │ │ │ │ ├── codemirrorOption.js │ │ │ │ │ ├── editor.js │ │ │ │ │ ├── editorCloseButton.js │ │ │ │ │ ├── editorLoad.js │ │ │ │ │ └── load.css │ │ │ │ ├── file.css │ │ │ │ ├── fileContainer.js │ │ │ │ ├── previewAudio │ │ │ │ │ ├── audio.js │ │ │ │ │ └── audioCloseButton.js │ │ │ │ ├── previewHtml │ │ │ │ │ ├── html.js │ │ │ │ │ └── htmlCloseButton.js │ │ │ │ ├── previewImg │ │ │ │ │ ├── image.js │ │ │ │ │ ├── imageCloseButton.js │ │ │ │ │ ├── imageZoomButton.js │ │ │ │ │ ├── zoom.css │ │ │ │ │ └── zoomAble.js │ │ │ │ └── previewVideo │ │ │ │ │ ├── video.js │ │ │ │ │ └── videoCloseButton.js │ │ │ ├── head │ │ │ │ ├── head.css │ │ │ │ ├── head.js │ │ │ │ ├── headLogo.js │ │ │ │ ├── headPath.js │ │ │ │ ├── headUser.js │ │ │ │ └── logo.jpg │ │ │ ├── home.js │ │ │ ├── msg.js │ │ │ ├── msg │ │ │ │ ├── msg.css │ │ │ │ ├── msgContainer.js │ │ │ │ └── msgContainerBtn.js │ │ │ ├── nav │ │ │ │ ├── nav.css │ │ │ │ ├── nav.js │ │ │ │ ├── navEcharts.js │ │ │ │ ├── navFile.js │ │ │ │ ├── navRecover.js │ │ │ │ ├── navSizeOption.js │ │ │ │ └── navTotalSize.js │ │ │ ├── recover │ │ │ │ ├── fileContainer │ │ │ │ │ ├── fileRecover.js │ │ │ │ │ ├── fileRecoverBody.js │ │ │ │ │ ├── fileRecoverDirItem.js │ │ │ │ │ ├── fileRecoverFileItem.js │ │ │ │ │ └── fileRecoverItemCheck.js │ │ │ │ ├── recoverContainer.js │ │ │ │ ├── recoverContainerHead.js │ │ │ │ ├── recoverContainerHeadCheckAll.js │ │ │ │ ├── recoverContainerHeadDeleteFile.js │ │ │ │ ├── recoverContainerHeadLeftBtn.js │ │ │ │ └── recoverContainerHeadRightBtn.js │ │ │ ├── redux │ │ │ │ ├── actionFunc.js │ │ │ │ └── globalStore.js │ │ │ ├── routeApp.js │ │ │ ├── tools │ │ │ │ ├── listFilter.js │ │ │ │ ├── requestData.js │ │ │ │ └── tools.js │ │ │ ├── welcome.js │ │ │ └── welcome │ │ │ │ ├── loginContainerBody.js │ │ │ │ ├── loginContainerCheckcode.js │ │ │ │ ├── loginContainerInit.js │ │ │ │ ├── loginContainerPassword.js │ │ │ │ ├── loginContainerSubmit.js │ │ │ │ ├── loginContainerUsername.js │ │ │ │ ├── registerContainerBody.js │ │ │ │ ├── registerContainerInit.js │ │ │ │ ├── registerContainerInviteCode.js │ │ │ │ ├── registerContainerPassword.js │ │ │ │ ├── registerContainerSubmit.js │ │ │ │ ├── registerContainerUsername.js │ │ │ │ ├── welcome.css │ │ │ │ ├── welcomeContainer.js │ │ │ │ ├── welcomeContainerFoot.js │ │ │ │ └── welcomeContainerHead.js │ │ ├── css │ │ │ ├── all.css │ │ │ ├── all.min.css │ │ │ ├── animate.css │ │ │ ├── background.css │ │ │ ├── basic.css │ │ │ └── loginBackground.jpg │ │ ├── entry.js │ │ ├── index.css │ │ ├── test.js │ │ └── webfonts │ │ │ ├── fa-brands-400.eot │ │ │ ├── fa-brands-400.svg │ │ │ ├── fa-brands-400.ttf │ │ │ ├── fa-brands-400.woff │ │ │ ├── fa-brands-400.woff2 │ │ │ ├── fa-regular-400.eot │ │ │ ├── fa-regular-400.svg │ │ │ ├── fa-regular-400.ttf │ │ │ ├── fa-regular-400.woff │ │ │ ├── fa-regular-400.woff2 │ │ │ ├── fa-solid-900.eot │ │ │ ├── fa-solid-900.svg │ │ │ ├── fa-solid-900.ttf │ │ │ ├── fa-solid-900.woff │ │ │ └── fa-solid-900.woff2 │ └── server │ │ ├── entry.ts │ │ ├── render.tsx │ │ ├── template │ │ ├── Body.tsx │ │ ├── Head.tsx │ │ └── index.tsx │ │ └── util.ts └── tsconfig.json ├── next-example ├── .gitignore ├── README.md ├── components │ └── Bar.tsx ├── index.js ├── next.config.mjs ├── package.json ├── pages │ ├── _app.tsx │ ├── _document.tsx │ ├── api │ │ └── hello.ts │ └── index.tsx ├── postcss.config.mjs ├── public │ ├── favicon.ico │ ├── next.svg │ └── vercel.svg ├── server.js ├── styles │ └── globals.css ├── tailwind.config.ts └── tsconfig.json ├── remix-example ├── .eslintrc.cjs ├── app │ ├── components │ │ └── Test.tsx │ ├── root.tsx │ ├── routes │ │ ├── Foo.tsx │ │ ├── _index.tsx │ │ └── action.set-theme.tsx │ ├── styles │ │ └── styles.css │ └── utils │ │ ├── theme-provider.tsx │ │ └── theme.server.ts ├── package.json ├── public │ └── favicon.ico ├── tsconfig.json └── vite.config.ts ├── rspack-example ├── index.html ├── package.json ├── rspack.config.js ├── src │ ├── App.tsx │ ├── ArrowFunction.tsx │ ├── ClassDefault.tsx │ ├── ClassNamed.tsx │ ├── FunctionDefault.tsx │ ├── FunctionNamed.tsx │ ├── LazyComponent.tsx │ └── index.tsx └── tsconfig.json ├── ssr-example ├── .browserslistrc ├── .env ├── .eslintrc.js ├── babel.config.js ├── build │ ├── scripts │ │ ├── build-prod.ts │ │ ├── build-static.ts │ │ ├── compiler.ts │ │ ├── config.ts │ │ ├── dynamic.ts │ │ ├── entry-dev.ts │ │ ├── entry-prod.ts │ │ ├── log.ts │ │ ├── start-app.js │ │ ├── start-dev.ts │ │ ├── startDevServer.ts │ │ └── startServerWatch.ts │ └── tsconfig.json ├── global.d.ts ├── lang │ ├── en.json │ └── zh.json ├── package.json ├── postcss.config.js ├── public │ ├── 1.png │ ├── 2.png │ ├── clock.png │ ├── favicon.ico │ ├── flag.png │ ├── mine.css │ ├── mine.js │ └── target.jpg ├── src │ ├── client │ │ ├── app.tsx │ │ ├── common │ │ │ ├── App.tsx │ │ │ ├── AutoInjectProps.tsx │ │ │ ├── Layout │ │ │ │ └── index.tsx │ │ │ ├── LoadingBar │ │ │ │ ├── LoadingBar.tsx │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── RenderMatch.tsx │ │ │ ├── WrapperApollo │ │ │ │ └── index.tsx │ │ │ ├── WrapperCatch │ │ │ │ └── index.tsx │ │ │ ├── WrapperDevTool │ │ │ │ └── index.tsx │ │ │ ├── WrapperLang │ │ │ │ └── index.tsx │ │ │ └── WrapperRoute │ │ │ │ └── index.tsx │ │ ├── component │ │ │ ├── Actor │ │ │ │ └── index.tsx │ │ │ ├── Arrow.tsx │ │ │ ├── BlogGrid │ │ │ │ ├── Item.tsx │ │ │ │ └── index.tsx │ │ │ ├── Card │ │ │ │ └── index.tsx │ │ │ ├── Chart │ │ │ │ └── index.tsx │ │ │ ├── ColorMode │ │ │ │ └── index.tsx │ │ │ ├── Comment │ │ │ │ ├── Item.tsx │ │ │ │ └── index.tsx │ │ │ ├── DevTool │ │ │ │ ├── Item.tsx │ │ │ │ └── index.tsx │ │ │ ├── Error │ │ │ │ └── index.tsx │ │ │ ├── Follower │ │ │ │ ├── Item.tsx │ │ │ │ └── index.tsx │ │ │ ├── Footer │ │ │ │ └── index.tsx │ │ │ ├── Game.tsx │ │ │ ├── GridCard │ │ │ │ └── index.tsx │ │ │ ├── GridLayout │ │ │ │ └── index.tsx │ │ │ ├── Header │ │ │ │ ├── GlobalStyle.tsx │ │ │ │ └── index.tsx │ │ │ ├── Hover │ │ │ │ └── index.tsx │ │ │ ├── Icons │ │ │ │ ├── LeetCode.tsx │ │ │ │ ├── NextJs.tsx │ │ │ │ ├── ReactRouter.tsx │ │ │ │ ├── Remix.tsx │ │ │ │ ├── Rspack.tsx │ │ │ │ ├── Vite.tsx │ │ │ │ ├── Webpack.tsx │ │ │ │ └── index.ts │ │ │ ├── LockBody │ │ │ │ └── index.tsx │ │ │ ├── ModuleManager │ │ │ │ ├── DesktopOverlay.tsx │ │ │ │ ├── MobileOverlay.tsx │ │ │ │ └── index.tsx │ │ │ ├── NextPlayground │ │ │ │ ├── config.ts │ │ │ │ └── index.tsx │ │ │ ├── Overlay │ │ │ │ ├── Desktop.tsx │ │ │ │ ├── Mobile.tsx │ │ │ │ └── index.ts │ │ │ ├── Reactive.tsx │ │ │ ├── Recommend │ │ │ │ └── index.tsx │ │ │ ├── RspackPlayground │ │ │ │ ├── config.ts │ │ │ │ └── index.tsx │ │ │ ├── ScrollControl │ │ │ │ ├── ScrollContent.tsx │ │ │ │ ├── ScrollControl.tsx │ │ │ │ ├── ScrollControlContext.ts │ │ │ │ ├── ScrollControlTool.tsx │ │ │ │ ├── ScrollSection.tsx │ │ │ │ ├── ScrollSectionContext.ts │ │ │ │ ├── ScrollToTop.tsx │ │ │ │ ├── ScrollViewContext.ts │ │ │ │ └── index.ts │ │ │ ├── Section.tsx │ │ │ ├── Table │ │ │ │ ├── BaseTable.tsx │ │ │ │ ├── Cell.tsx │ │ │ │ ├── Column.tsx │ │ │ │ ├── ErrorCatch.tsx │ │ │ │ ├── HeadCell.tsx │ │ │ │ ├── Pagination.tsx │ │ │ │ ├── Td.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── type.ts │ │ │ │ ├── useChildren.tsx │ │ │ │ ├── usePaginationController.tsx │ │ │ │ ├── useSkeleton.tsx │ │ │ │ └── useSorter.ts │ │ │ ├── ThreeFiber │ │ │ │ ├── AutoDispose.tsx │ │ │ │ ├── ContextMenuOverride.tsx │ │ │ │ ├── MultiMaterial.tsx │ │ │ │ ├── MultiRender.tsx │ │ │ │ ├── Pointcloud.tsx │ │ │ │ ├── Reparenting.tsx │ │ │ │ ├── Simple.tsx │ │ │ │ ├── SuspenseMaterial.tsx │ │ │ │ └── index.tsx │ │ │ ├── VitePlayground │ │ │ │ ├── config.ts │ │ │ │ └── index.tsx │ │ │ └── index.ts │ │ ├── config │ │ │ ├── container.ts │ │ │ ├── gridLayout.ts │ │ │ └── source.ts │ │ ├── container │ │ │ ├── BlogList │ │ │ │ └── index.tsx │ │ │ ├── BlogModal │ │ │ │ ├── DetailModal.tsx │ │ │ │ └── index.tsx │ │ │ ├── Section │ │ │ │ ├── Api.tsx │ │ │ │ ├── DevTool.tsx │ │ │ │ ├── Main.tsx │ │ │ │ ├── Next.tsx │ │ │ │ ├── Reconciler.tsx │ │ │ │ ├── ThreeFiber.tsx │ │ │ │ ├── Vite.tsx │ │ │ │ └── index.ts │ │ │ └── User │ │ │ │ └── index.tsx │ │ ├── entry.tsx │ │ ├── hooks │ │ │ ├── index.ts │ │ │ ├── useDebouncedState.ts │ │ │ ├── useDevTool.ts │ │ │ ├── useEffectOnce.ts │ │ │ ├── useFoot.ts │ │ │ ├── useGetInitialProps.ts │ │ │ ├── useHead.ts │ │ │ ├── useIsMobile.ts │ │ │ ├── useIsMounted.ts │ │ │ ├── useLang.ts │ │ │ ├── useLoadingBar.ts │ │ │ ├── useLoadingStore.ts │ │ │ ├── useLockBodyScroll.ts │ │ │ ├── useMainCard.ts │ │ │ ├── useOverlay.ts │ │ │ ├── usePreLoad.ts │ │ │ ├── useSize.ts │ │ │ ├── useUpdate.ts │ │ │ └── useWindowSize.ts │ │ ├── pages │ │ │ ├── 404.tsx │ │ │ ├── About.tsx │ │ │ ├── Blog.tsx │ │ │ ├── Excalidraw.tsx │ │ │ └── index.tsx │ │ ├── router │ │ │ ├── dynamicRoutes.ts │ │ │ ├── index.ts │ │ │ ├── routers.loadable.ts │ │ │ ├── routers.stream.ts │ │ │ └── routes.ts │ │ ├── store │ │ │ ├── Time.ts │ │ │ └── index.ts │ │ ├── styles │ │ │ └── global.scss │ │ ├── types │ │ │ ├── common.ts │ │ │ ├── hooks.ts │ │ │ ├── route.ts │ │ │ └── util.ts │ │ └── utils │ │ │ ├── code.ts │ │ │ ├── cx.ts │ │ │ ├── delay.ts │ │ │ ├── dom.ts │ │ │ ├── highlight.ts │ │ │ ├── index.ts │ │ │ ├── log.ts │ │ │ ├── markdown.ts │ │ │ ├── preLoad.ts │ │ │ ├── scroll.ts │ │ │ └── time.ts │ ├── server │ │ ├── api │ │ │ ├── index.ts │ │ │ └── lang.ts │ │ ├── app.ts │ │ ├── entry.ts │ │ ├── generator │ │ │ ├── index.ts │ │ │ └── util.ts │ │ ├── middleware │ │ │ ├── apiHandler.ts │ │ │ ├── develop │ │ │ │ ├── index.ts │ │ │ │ └── webpackMiddleware.ts │ │ │ ├── render.ts │ │ │ ├── renderError.tsx │ │ │ └── renderPage │ │ │ │ ├── compose.ts │ │ │ │ ├── index.ts │ │ │ │ ├── middleware │ │ │ │ ├── globalEnv.ts │ │ │ │ ├── index.ts │ │ │ │ ├── initLang.ts │ │ │ │ ├── initStore.ts │ │ │ │ ├── loadAsset.ts │ │ │ │ ├── loadLang.ts │ │ │ │ └── loadStore.ts │ │ │ │ ├── native │ │ │ │ ├── renderCSR.tsx │ │ │ │ ├── renderP_CSR.tsx │ │ │ │ ├── renderPipeStreamSSR.tsx │ │ │ │ └── renderSSR.tsx │ │ │ │ └── render │ │ │ │ └── webpackRender.ts │ │ ├── static │ │ │ ├── index.ts │ │ │ └── util.ts │ │ ├── type.ts │ │ └── util │ │ │ ├── element.ts │ │ │ ├── loadableManifest.ts │ │ │ ├── renderError.ts │ │ │ ├── serverLog.ts │ │ │ ├── viteManifest.ts │ │ │ └── webpackManifest.ts │ └── shared │ │ ├── emotionCache.ts │ │ ├── env.ts │ │ ├── i18n.ts │ │ ├── index.ts │ │ ├── safeData.ts │ │ ├── store │ │ ├── action.ts │ │ ├── index.ts │ │ ├── reducer │ │ │ ├── client │ │ │ │ ├── action │ │ │ │ │ ├── clientLang.ts │ │ │ │ │ ├── clientProps.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ ├── share │ │ │ │ │ └── action.ts │ │ │ │ └── type.ts │ │ │ ├── index.ts │ │ │ └── server │ │ │ │ ├── action │ │ │ │ ├── index.ts │ │ │ │ └── serverLang.ts │ │ │ │ ├── index.ts │ │ │ │ ├── share │ │ │ │ └── action.ts │ │ │ │ └── type.ts │ │ ├── saga │ │ │ ├── action │ │ │ │ ├── index.ts │ │ │ │ └── langSaga.ts │ │ │ ├── index.ts │ │ │ └── utils.ts │ │ └── type.ts │ │ ├── template │ │ ├── Body.tsx │ │ ├── Head.tsx │ │ └── index.tsx │ │ └── theme │ │ ├── index.ts │ │ ├── semanticTokens.ts │ │ └── styles.ts └── tsconfig.json ├── vite-example ├── index.html ├── package.json ├── public │ ├── favicon.ico │ └── vite.svg ├── src │ ├── App.css │ ├── App.tsx │ ├── assets │ │ └── react.svg │ ├── index.css │ ├── main.tsx │ └── vite.d.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts └── vite-ssr-example ├── index.html ├── package.json ├── public ├── favicon.ico └── vite.svg ├── server.mjs ├── src ├── App.css ├── App.tsx ├── components │ └── B.tsx ├── entry-client.tsx ├── entry-server.tsx ├── index.css ├── page │ ├── Foo.tsx │ └── Home.tsx └── vite.d.ts ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true, 5 | }, 6 | // eslint will auto add `eslint-config` for a no scope package(which not start with '@' chart), so here use absolute file path 7 | extends: [require.resolve("project-tool/baseLint")], 8 | ignorePatterns: ["dist", "dev", "lib", "__tests__", "bundle", "ui/vite-example"], 9 | rules: { 10 | "@typescript-eslint/no-unused-expressions": "off", 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | .cache 3 | .idea 4 | .eslintcache 5 | .DS_Store 6 | node_modules 7 | dev 8 | dist 9 | -------------------------------------------------------------------------------- /.graphqlrc.yml: -------------------------------------------------------------------------------- 1 | schema: "site/graphql/schema.graphql" 2 | documents: "site/graphql/src/document/*.graphql" 3 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | # 运行清理类型的脚本 2 | echo "Running clean:type..." 3 | pnpm run clean:type 4 | 5 | # 将生成的修改添加到当前提交中 6 | echo "Adding changes to commit..." 7 | git add . -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | strict-peer-dependencies=false 2 | prefer-workspace-packages=true 3 | link-workspace-packages=true -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | **/dist 3 | **/dev 4 | **/bundle 5 | pnpm-lock.yaml -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "trailingComma": "es5", 4 | "singleQuote": false, 5 | "tabWidth": 2, 6 | "useTabs": false, 7 | "printWidth": 160 8 | } 9 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "commentTranslate.source": "Bing", 3 | "typescript.tsdk": "node_modules/typescript/lib" 4 | } 5 | -------------------------------------------------------------------------------- /commit.mjs: -------------------------------------------------------------------------------- 1 | import { testGithub } from "@test/react-terminal"; 2 | 3 | testGithub(); 4 | -------------------------------------------------------------------------------- /global.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | const __DEV__: boolean; 3 | const __VERSION__: string; 4 | 5 | namespace NodeJS { 6 | interface ProcessEnv { 7 | NODE_ENV: "development" | "production" | "test"; 8 | } 9 | } 10 | } 11 | 12 | export {}; 13 | -------------------------------------------------------------------------------- /packages/myreact-dom/client.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const React = require("react"); 4 | 5 | if (!React.isMyReact) { 6 | throw new Error( 7 | "@my-react/react-dom requires 'React' to be set as '@my-react/react'. Please ensure you have set the alias correctly in your bundler configuration." 8 | ); 9 | } 10 | 11 | if (process.env.NODE_ENV === "production") { 12 | module.exports = require("./dist/cjs/index.production"); 13 | } else { 14 | module.exports = require("./dist/cjs/index.development"); 15 | } 16 | -------------------------------------------------------------------------------- /packages/myreact-dom/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const React = require("react"); 4 | 5 | if (!React.isMyReact) { 6 | throw new Error( 7 | "@my-react/react-dom requires 'React' to be set as '@my-react/react'. Please ensure you have set the alias correctly in your bundler configuration." 8 | ); 9 | } 10 | 11 | if (process.env.NODE_ENV === "production") { 12 | module.exports = require("./dist/cjs/index.production"); 13 | } else { 14 | module.exports = require("./dist/cjs/index.development"); 15 | } 16 | -------------------------------------------------------------------------------- /packages/myreact-dom/readme.md: -------------------------------------------------------------------------------- 1 | ## @my-react/react-dom 2 | 3 | this package just like ReactDOM, which help to render @my-react element to the dom 4 | 5 | see https://mrwangjusttodo.github.io/MyReact/ 6 | 7 | ```shell 8 | pnpm add @my-react/react-dom 9 | ``` 10 | -------------------------------------------------------------------------------- /packages/myreact-dom/server.browser.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const React = require("react"); 4 | 5 | if (!React.isMyReact) { 6 | throw new Error( 7 | "@my-react/react-dom requires 'React' to be set as '@my-react/react'. Please ensure you have set the alias correctly in your bundler configuration." 8 | ); 9 | } 10 | 11 | if (process.env.NODE_ENV === "production") { 12 | module.exports = require("./dist/cjs/server.production"); 13 | } else { 14 | module.exports = require("./dist/cjs/server.development"); 15 | } 16 | -------------------------------------------------------------------------------- /packages/myreact-dom/server.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const React = require("react"); 4 | 5 | if (!React.isMyReact) { 6 | throw new Error( 7 | "@my-react/react-dom requires 'React' to be set as '@my-react/react'. Please ensure you have set the alias correctly in your bundler configuration." 8 | ); 9 | } 10 | 11 | if (process.env.NODE_ENV === "production") { 12 | module.exports = require("./dist/cjs/server.production"); 13 | } else { 14 | module.exports = require("./dist/cjs/server.development"); 15 | } 16 | -------------------------------------------------------------------------------- /packages/myreact-dom/server.node.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const React = require("react"); 4 | 5 | if (!React.isMyReact) { 6 | throw new Error( 7 | "@my-react/react-dom requires 'React' to be set as '@my-react/react'. Please ensure you have set the alias correctly in your bundler configuration." 8 | ); 9 | } 10 | 11 | if (process.env.NODE_ENV === "production") { 12 | module.exports = require("./dist/cjs/server.production"); 13 | } else { 14 | module.exports = require("./dist/cjs/server.development"); 15 | } 16 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/client/api/clear/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/client/api/create/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/client/api/fallback/feature.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @internal 3 | */ 4 | export const fallback = (el?: ChildNode) => { 5 | if (el) { 6 | const sibling = el.nextSibling; 7 | 8 | el?.remove(); 9 | 10 | fallback(sibling); 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/client/api/fallback/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/client/api/helper/attr/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./setAttr"; 2 | export * from "./setText"; 3 | export * from "./setInnerHtml"; 4 | export * from "./namespace"; 5 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/client/api/helper/attr/namespace.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @internal 3 | */ 4 | export const XLINK_NS = "http://www.w3.org/1999/xlink"; 5 | 6 | /** 7 | * @internal 8 | */ 9 | export const XML_NS = "http://www.w3.org/2000/xmlns/"; 10 | 11 | /** 12 | * @internal 13 | */ 14 | export const X_CHAR = 120; 15 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/client/api/helper/event/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./addEvent"; 2 | export * from "./removeEvent"; 3 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/client/api/helper/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./control"; 2 | export * from "./event"; 3 | export * from "./style"; 4 | export * from "./attr"; 5 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/client/api/helper/style/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./setStyle"; 2 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/client/api/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./helper"; 2 | export * from "./clear"; 3 | export * from "./append"; 4 | export * from "./create"; 5 | export * from "./update"; 6 | export * from "./position"; 7 | export * from "./fallback"; 8 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/client/api/position/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/client/api/update/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | export * from "./tool"; 3 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/client/dispatchMount/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/client/mount/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./render"; 2 | export * from "./hydrate"; 3 | export * from "./createRoot"; 4 | export * from "./hydrateRoot"; 5 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/client/renderDispatch/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./instance"; 2 | export * from "./dispatch"; 3 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/client/tools/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./createPortal"; 2 | export * from "./findDOMNode"; 3 | export * from "./hmr"; 4 | export * from "./ref"; 5 | export * from "./debug"; 6 | export * from "./unmountComponentAtNode"; 7 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/global.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | const __DEV__: boolean; 3 | const __VERSION__: string; 4 | 5 | const scheduler: any; 6 | 7 | namespace NodeJS { 8 | interface ProcessEnv { 9 | NODE_ENV: "development" | "production" | "test"; 10 | } 11 | } 12 | 13 | interface Window { 14 | __highlight__: boolean; 15 | } 16 | } 17 | 18 | export {}; 19 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./client"; 2 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/noop/mount/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./render"; 2 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/noop/renderDispatch/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./instance"; 2 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/noop/renderDispatch/unmount.ts: -------------------------------------------------------------------------------- 1 | import { generateFiberToUnmountList, unmountList } from "@my-react/react-reconciler"; 2 | 3 | import type { CustomRenderDispatch, MyReactFiberNode } from "@my-react/react-reconciler"; 4 | 5 | export const unmount = (_dispatch: CustomRenderDispatch, _pending: MyReactFiberNode) => { 6 | const list = generateFiberToUnmountList(_pending); 7 | 8 | unmountList(_dispatch, list); 9 | }; 10 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/server/api/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./append"; 2 | export * from "./create"; 3 | export * from "./update"; 4 | export * from "./native"; 5 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/server/api/native/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./text"; 2 | export * from "./plain"; 3 | export * from "./comment"; 4 | export * from "./container"; 5 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/server/api/native/text.ts: -------------------------------------------------------------------------------- 1 | import type { PlainElement } from "./plain"; 2 | import type { MyReactElementNode } from "@my-react/react"; 3 | import type { MyReactFiberNode } from "@my-react/react-reconciler"; 4 | 5 | /** 6 | * @internal 7 | */ 8 | export class TextElement { 9 | content = ""; 10 | parentElement: PlainElement | null = null; 11 | 12 | constructor(content: string) { 13 | this.content = content === "" ? " " : content; 14 | } 15 | 16 | toString() { 17 | return this.content.toString(); 18 | } 19 | } 20 | 21 | /** 22 | * @internal 23 | */ 24 | export class TextElementDev extends TextElement { 25 | _debugFiber: MyReactFiberNode; 26 | _debugElement: MyReactElementNode; 27 | } 28 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/server/mount/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./renderToString"; 2 | export * from "./renderToNodeStream"; 3 | export * from "./renderToStaticMarkup"; 4 | export * from "./renderToReadableStream"; 5 | export * from "./renderToPipeableStream"; 6 | export * from "./renderToStaticNodeStream"; 7 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/server/renderDispatch/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./serverDomDispatch"; 2 | export * from "./serverStreamDispatch"; 3 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/server/renderDispatch/unmount.ts: -------------------------------------------------------------------------------- 1 | import { generateFiberToUnmountList, unmountList } from "@my-react/react-reconciler"; 2 | 3 | import type { CustomRenderDispatch, MyReactFiberNode } from "@my-react/react-reconciler"; 4 | 5 | export const unmount = (_dispatch: CustomRenderDispatch, _pending: MyReactFiberNode) => { 6 | const list = generateFiberToUnmountList(_pending); 7 | 8 | unmountList(_dispatch, list); 9 | }; 10 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/shared/comment.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @internal 3 | */ 4 | export const commentS = " [ "; 5 | 6 | /** 7 | * @internal 8 | */ 9 | export const commentE = " ] "; 10 | 11 | /** 12 | * @internal 13 | */ 14 | export const commentS_ = '$'; 15 | 16 | /** 17 | * @internal 18 | */ 19 | export const commentE_ = '/$'; 20 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/shared/dom.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @internal 3 | */ 4 | export type DomElement = Element; 5 | 6 | /** 7 | * @internal 8 | */ 9 | export type DomNode = Node; 10 | 11 | /** 12 | * @internal 13 | */ 14 | export type DomComment = Comment; 15 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/shared/elementStyle.ts: -------------------------------------------------------------------------------- 1 | import { makeMap } from "./tools"; 2 | 3 | /** 4 | * @internal 5 | */ 6 | export const isUnitlessNumber = makeMap( 7 | "animationIterationCount,borderImageOutset,borderImageSlice,borderImageWidth,boxFlex," + 8 | "boxFlexGroup,boxOrdinalGroup,columnCount,columns,flex,flexGrow,flexPositive,flexShrink," + 9 | "flexNegative,flexOrder,gridArea,gridRow,gridRowEnd,gridRowSpan,gridRowStart,gridColumn," + 10 | "gridColumnEnd,gridColumnSpan,gridColumnStart,fontWeight,lineClamp,lineHeight,opacity,order," + 11 | "orphans,tabSize,widows,zIndex,zoom,fillOpacity,floodOpacity,stopOpacity,strokeDasharray," + 12 | "strokeDashoffset,strokeMiterlimit,strokeOpacity,strokeWidth" 13 | ); 14 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/shared/head.ts: -------------------------------------------------------------------------------- 1 | import { NODE_TYPE, type CustomRenderDispatch, type MyReactFiberNode } from "@my-react/react-reconciler"; 2 | import { include, STATE_TYPE, ListTree } from "@my-react/react-shared"; 3 | 4 | export const rerunHead = (renderDispatch: CustomRenderDispatch, fiber: MyReactFiberNode) => { 5 | if (include(fiber.type, NODE_TYPE.__plain__) && fiber.elementType === "head" && fiber.state !== STATE_TYPE.__reschedule__) { 6 | fiber.state = STATE_TYPE.__stable__; 7 | 8 | renderDispatch.pendingAsyncLoadList = renderDispatch.pendingAsyncLoadList || new ListTree(); 9 | 10 | renderDispatch.pendingAsyncLoadList.pushToLast(fiber); 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/shared/kebabCase.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-unsafe-function-type */ 2 | const memorize = (fn: T): T => { 3 | const map: Record = {}; 4 | return ((...p: any[]) => { 5 | const key = p.join(","); 6 | if (key in map) { 7 | return map[key]; 8 | } 9 | map[key] = fn.call(null, ...p); 10 | return map[key]; 11 | }) as unknown as T; 12 | }; 13 | 14 | /** 15 | * @internal 16 | */ 17 | export const kebabCase = memorize((s: string) => s.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase()); 18 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/shared/promise.ts: -------------------------------------------------------------------------------- 1 | export const createControlPromise = () => { 2 | let resolve: (value: T) => void; 3 | let reject: (reason: Error) => void; 4 | const promise = new Promise((res, rej) => { 5 | resolve = res; 6 | reject = rej; 7 | }); 8 | return { promise, resolve: resolve!, reject: reject! }; 9 | } -------------------------------------------------------------------------------- /packages/myreact-dom/src/shared/shouldPause.ts: -------------------------------------------------------------------------------- 1 | import { asyncUpdateTimeLimit, asyncUpdateTimeStep } from "./env"; 2 | 3 | /** 4 | * @internal 5 | */ 6 | export const shouldPauseAsyncUpdate = () => { 7 | if (!asyncUpdateTimeStep.current) { 8 | asyncUpdateTimeStep.current = Date.now(); 9 | return false; 10 | } else { 11 | const now = Date.now(); 12 | const result = now - asyncUpdateTimeStep.current > asyncUpdateTimeLimit.current; 13 | if (result) asyncUpdateTimeStep.current = null; 14 | return result; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/shared/validate.ts: -------------------------------------------------------------------------------- 1 | import { NODE_TYPE } from "@my-react/react-reconciler"; 2 | import { include } from "@my-react/react-shared"; 3 | 4 | import type { MyReactFiberNode } from "@my-react/react-reconciler"; 5 | 6 | /** 7 | * @internal 8 | */ 9 | export const checkRoot = (fiber: MyReactFiberNode) => { 10 | if (include(fiber.type, NODE_TYPE.__class__)) return; 11 | 12 | if (include(fiber.type, NODE_TYPE.__function__)) return; 13 | 14 | if (include(fiber.type, NODE_TYPE.__portal__)) return; 15 | 16 | return; 17 | 18 | // throw new Error(`[@my-react/react-dom] the root element should be a dynamic node such as 'function' or 'class'`) 19 | }; 20 | -------------------------------------------------------------------------------- /packages/myreact-dom/src/shared/validateTag.ts: -------------------------------------------------------------------------------- 1 | import { NODE_TYPE, type MyReactFiberNode } from "@my-react/react-reconciler"; 2 | import { include } from "@my-react/react-shared"; 3 | 4 | import { isHTMLTag, isSVGTag } from "./elementTag"; 5 | import { logOnce } from "./log"; 6 | 7 | /** 8 | * @internal 9 | */ 10 | export const validDomTag = (fiber: MyReactFiberNode) => { 11 | if (include(fiber.type, NODE_TYPE.__plain__)) { 12 | const tagName = fiber.elementType as string; 13 | 14 | if (!isHTMLTag[tagName] && !isSVGTag[tagName]) { 15 | // custom element 16 | if (!customElements.get(tagName)) { 17 | logOnce(fiber, "error", "invalid dom tag", `invalid dom tag, current is "${tagName}"`); 18 | } 19 | } 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /packages/myreact-dom/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "target": "ES5", 5 | "esModuleInterop": true, 6 | "stripInternal": true, 7 | "paths": { 8 | "@my-react-dom-shared": ["./src/shared"], 9 | "@my-react-dom-server": ["./src/server"], 10 | "@my-react-dom-server/*": ["./src/server/*"], 11 | "@my-react-dom-client": ["./src/client"], 12 | "@my-react-dom-client/*": ["./src/client/*"], 13 | "@my-react-dom-noop": ["./src/noop"], 14 | "@my-react-dom-noop/*": ["./src/noop/*"] 15 | } 16 | }, 17 | "include": ["./src"], 18 | "exclude": ["node_modules"] 19 | } 20 | -------------------------------------------------------------------------------- /packages/myreact-jsx/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | if (process.env.NODE_ENV === "production") { 4 | module.exports = require("./dist/cjs/index.production"); 5 | } else { 6 | module.exports = require("./dist/cjs/index.development"); 7 | } 8 | -------------------------------------------------------------------------------- /packages/myreact-jsx/jsx-dev-runtime.d.ts: -------------------------------------------------------------------------------- 1 | import { jsxDEV, Fragment } from "./dist/types/index"; 2 | 3 | export { jsxDEV, Fragment }; 4 | -------------------------------------------------------------------------------- /packages/myreact-jsx/jsx-dev-runtime.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = require("./dist/cjs/index.development"); 4 | -------------------------------------------------------------------------------- /packages/myreact-jsx/jsx-runtime.d.ts: -------------------------------------------------------------------------------- 1 | import { jsx, jsxs, Fragment } from "./dist/types/index"; 2 | 3 | export { jsx, jsxs, Fragment }; 4 | -------------------------------------------------------------------------------- /packages/myreact-jsx/jsx-runtime.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = require("./dist/cjs/index.production"); 4 | -------------------------------------------------------------------------------- /packages/myreact-jsx/readme.md: -------------------------------------------------------------------------------- 1 | ## @my-react/react-jsx 2 | 3 | this package just like react-jsx, which help to do the jsx transform 4 | 5 | see https://mrwangjusttodo.github.io/MyReact/ 6 | -------------------------------------------------------------------------------- /packages/myreact-jsx/src/global.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | const __DEV__: boolean; 3 | const __VERSION__: string; 4 | 5 | namespace NodeJS { 6 | interface ProcessEnv { 7 | NODE_ENV: "development" | "production" | "test"; 8 | } 9 | } 10 | } 11 | 12 | export {}; 13 | -------------------------------------------------------------------------------- /packages/myreact-jsx/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./instance"; 2 | -------------------------------------------------------------------------------- /packages/myreact-jsx/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "target": "ES5", 5 | "stripInternal": true 6 | }, 7 | "include": ["./src"], 8 | "exclude": ["node_modules"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/myreact-reactivity/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from "./dist/types"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reactivity/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | if (process.env.NODE_ENV === "production") { 4 | module.exports = require("./dist/cjs/index.production"); 5 | } else { 6 | module.exports = require("./dist/cjs/index.development"); 7 | } 8 | -------------------------------------------------------------------------------- /packages/myreact-reactivity/src/api/createRef.ts: -------------------------------------------------------------------------------- 1 | function createRef(value: T) { 2 | return { current: value }; 3 | } 4 | 5 | export { createRef }; 6 | -------------------------------------------------------------------------------- /packages/myreact-reactivity/src/api/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./ref"; 2 | export * from "./watch"; 3 | export * from "./effect"; 4 | export * from "./reactive"; 5 | export * from "./computed"; 6 | -------------------------------------------------------------------------------- /packages/myreact-reactivity/src/api/symbol.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @internal 3 | */ 4 | export const enum ReactiveFlags { 5 | Reactive_key = "__my_reactive__", 6 | Readonly_key = "__my_readonly__", 7 | Shallow_key = "__my_shallow__", 8 | Skip_key = "__my_skip__", 9 | Raw_key = "__my_raw__", 10 | } 11 | 12 | /** 13 | * @internal 14 | */ 15 | export const enum RefFlags { 16 | Ref_key = "__my_ref__", 17 | } 18 | 19 | /** 20 | * @internal 21 | */ 22 | export const enum EffectFlags { 23 | Effect_key = "__my_effect__", 24 | } 25 | 26 | /** 27 | * @internal 28 | */ 29 | export const enum ComputedFlags { 30 | Computed_key = "__my_computed__", 31 | } 32 | -------------------------------------------------------------------------------- /packages/myreact-reactivity/src/global.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | const __DEV__: boolean; 3 | const __VERSION__: string; 4 | 5 | namespace NodeJS { 6 | interface ProcessEnv { 7 | NODE_ENV: "development" | "production" | "test"; 8 | } 9 | } 10 | } 11 | 12 | export {}; 13 | -------------------------------------------------------------------------------- /packages/myreact-reactivity/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./api"; 2 | 3 | export { createReactive, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onMounted, onUnmounted, onUpdated } from "./reactive"; 4 | 5 | const version = __VERSION__; 6 | 7 | export { version }; 8 | -------------------------------------------------------------------------------- /packages/myreact-reactivity/src/share/globalMap.ts: -------------------------------------------------------------------------------- 1 | import type { ReactiveEffect } from "../api"; 2 | 3 | export const globalDepsMap = new WeakMap | unknown[], Map>>(); 4 | 5 | export const globalReactiveMap = new WeakMap, Record>(); 6 | 7 | export const globalReadOnlyMap = new WeakMap, Record>(); 8 | 9 | export const globalShallowReactiveMap = new WeakMap, Record>(); 10 | 11 | export const globalShallowReadOnlyMap = new WeakMap, Record>(); 12 | -------------------------------------------------------------------------------- /packages/myreact-reactivity/src/share/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./globalMap"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reactivity/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "target": "ES5", 5 | "stripInternal": true 6 | }, 7 | "include": ["./src"], 8 | "exclude": ["node_modules"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/myreact-reconciler-compact/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from "./dist/types"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler-compact/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const React = require("react"); 4 | 5 | if (!React.isMyReact) { 6 | throw new Error( 7 | "@my-react/react-reconciler-compact requires 'React' to be set as '@my-react/react'. Please ensure you have set the alias correctly in your bundler configuration." 8 | ); 9 | } 10 | 11 | if (process.env.NODE_ENV === "production") { 12 | module.exports = require("./dist/cjs/index.production"); 13 | } else { 14 | module.exports = require("./dist/cjs/index.development"); 15 | } 16 | -------------------------------------------------------------------------------- /packages/myreact-reconciler-compact/src/api/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./ref"; 2 | export * from "./create"; 3 | export * from "./append"; 4 | export * from "./update"; 5 | export * from "./remove"; 6 | export * from "./position"; 7 | -------------------------------------------------------------------------------- /packages/myreact-reconciler-compact/src/global.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | const __DEV__: boolean; 3 | const __VERSION__: string; 4 | 5 | namespace NodeJS { 6 | interface ProcessEnv { 7 | NODE_ENV: "development" | "production" | "test"; 8 | } 9 | } 10 | } 11 | 12 | export {}; 13 | -------------------------------------------------------------------------------- /packages/myreact-reconciler-compact/src/hmr.ts: -------------------------------------------------------------------------------- 1 | import type { ReconcilerDispatch } from "./dispatch"; 2 | import type { CustomRenderDispatch } from "@my-react/react-reconciler"; 3 | 4 | const DEV_REFRESH_FIELD = "__@my-react/react-refresh-inject__"; 5 | 6 | type RefreshRuntime = (dispatch: CustomRenderDispatch) => void; 7 | 8 | export const autoSetDevHMR = (dispatch: ReconcilerDispatch) => { 9 | if (__DEV__) { 10 | if (typeof globalThis !== "undefined" && globalThis[DEV_REFRESH_FIELD]) { 11 | try { 12 | const typedRuntimeField = globalThis[DEV_REFRESH_FIELD] as RefreshRuntime; 13 | 14 | typedRuntimeField?.(dispatch); 15 | } catch { 16 | void 0; 17 | } 18 | } 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /packages/myreact-reconciler-compact/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Reconciler } from "./feature"; 2 | 3 | import type { MyReactFiberNode } from "@my-react/react-reconciler"; 4 | import type createReconcilerType from "react-reconciler"; 5 | 6 | export * from "@my-react/react-reconciler"; 7 | 8 | export const version = __VERSION__; 9 | 10 | export const createReconciler = Reconciler as unknown as typeof createReconcilerType; 11 | 12 | export interface FiberNode> extends MyReactFiberNode { 13 | stateNode: T; 14 | return: FiberNode | null; 15 | child: FiberNode | null; 16 | sibling: FiberNode | null; 17 | alternate?: FiberNode | null; 18 | } 19 | -------------------------------------------------------------------------------- /packages/myreact-reconciler-compact/src/scheduler.ts: -------------------------------------------------------------------------------- 1 | import { __my_react_shared__ } from "@my-react/react"; 2 | import { enableFiberForLog, enableValidMyReactElement, initScheduler } from "@my-react/react-reconciler"; 3 | 4 | const { enableDebugFiled, enableScopeTreeLog } = __my_react_shared__; 5 | 6 | /** 7 | * @internal 8 | */ 9 | export const prepareScheduler = () => { 10 | enableDebugFiled.current = true; 11 | 12 | enableScopeTreeLog.current = true; 13 | 14 | enableFiberForLog.current = true; 15 | 16 | enableValidMyReactElement.current = false; 17 | 18 | initScheduler(); 19 | }; 20 | -------------------------------------------------------------------------------- /packages/myreact-reconciler-compact/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "target": "ES5", 5 | "esModuleInterop": true 6 | }, 7 | "include": ["./src"], 8 | "exclude": ["node_modules"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from "./dist/types"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | if (process.env.NODE_ENV === "production") { 4 | module.exports = require("./dist/cjs/index.production"); 5 | } else { 6 | module.exports = require("./dist/cjs/index.development"); 7 | } 8 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/dispatchContext/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/dispatchEffect/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/dispatchErrorBoundaries/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/dispatchFiber/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/dispatchMount/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/dispatchScope/feature.ts: -------------------------------------------------------------------------------- 1 | import { include } from "@my-react/react-shared"; 2 | 3 | import { NODE_TYPE } from "../share"; 4 | 5 | import type { MyReactFiberNode } from "../runtimeFiber"; 6 | 7 | export const defaultResolveScope = (fiber: MyReactFiberNode) => { 8 | let parent = fiber.parent; 9 | 10 | while (parent) { 11 | if (include(parent.type, NODE_TYPE.__scope__) || include(parent.type, NODE_TYPE.__scopeSuspense__)) { 12 | return parent; 13 | } 14 | parent = parent.parent; 15 | } 16 | 17 | return null; 18 | }; 19 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/dispatchScope/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/dispatchStrict/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/dispatchSuspense/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/dispatchUnmount/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/dispatchUpdate/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/global.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | const __DEV__: boolean; 3 | const __VERSION__: string; 4 | 5 | namespace NodeJS { 6 | interface ProcessEnv { 7 | NODE_ENV: "development" | "production" | "test"; 8 | } 9 | } 10 | } 11 | 12 | export {}; 13 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/processClass/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/processContext/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/processFunction/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/processHook/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/processLazy/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/processPromise/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/processQueue/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/processState/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/processSuspense/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/renderDispatch/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./event"; 2 | export * from "./interface"; 3 | export * from "./instance"; 4 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/renderMount/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/renderNextWork/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/renderUnmount/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/renderUpdate/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | export * from "./schedule"; 3 | export * from "./trigger"; 4 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/runtimeFiber/check.ts: -------------------------------------------------------------------------------- 1 | import type { MyReactFiberNode } from "./instance"; 2 | 3 | export const checkIsMyReactFiberNode = (fiber: unknown): fiber is MyReactFiberNode => { 4 | return ( 5 | fiber && 6 | typeof fiber === "object" && 7 | fiber.constructor && 8 | fiber.constructor.prototype && 9 | Object.prototype.hasOwnProperty.call(fiber.constructor.prototype, "isMyReactFiberNode") && 10 | fiber.constructor.prototype.isMyReactFiberNode 11 | ); 12 | }; 13 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/runtimeFiber/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./hmr"; 2 | export * from "./clear"; 3 | export * from "./check"; 4 | export * from "./create"; 5 | export * from "./update"; 6 | export * from "./trigger"; 7 | export * from "./initial"; 8 | export * from "./unmount"; 9 | export * from "./instance"; 10 | export * from "./interface"; 11 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/runtimeGenerate/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./generate"; 2 | export * from "./invoke"; 3 | export * from "./instance"; 4 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/runtimeHook/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./create"; 2 | export * from "./effect"; 3 | export * from "./update"; 4 | export * from "./unmount"; 5 | export * from "./instance"; 6 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/runtimeMount/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/runtimeScope/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/runtimeUpdate/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/share/fiberType.ts: -------------------------------------------------------------------------------- 1 | export enum NODE_TYPE { 2 | __initial__ = 0, 3 | __class__ = 1 << 0, 4 | __function__ = 1 << 1, 5 | __lazy__ = 1 << 2, 6 | __memo__ = 1 << 3, 7 | __forwardRef__ = 1 << 4, 8 | __provider__ = 1 << 5, 9 | __consumer__ = 1 << 6, 10 | __portal__ = 1 << 7, 11 | __null__ = 1 << 8, 12 | __text__ = 1 << 9, 13 | __empty__ = 1 << 10, 14 | __plain__ = 1 << 11, 15 | __strict__ = 1 << 12, 16 | __suspense__ = 1 << 13, 17 | __fragment__ = 1 << 14, 18 | __root__ = 1 << 15, 19 | __scope__ = 1 << 16, 20 | __comment__ = 1 << 17, 21 | __profiler__ = 1 << 18, 22 | __context__ = 1 << 19, 23 | __scopeLazy__ = 1 << 20, 24 | __scopeSuspense__ = 1 << 21, 25 | } 26 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/share/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./map"; 2 | export * from "./env"; 3 | export * from "./hmr"; 4 | export * from "./sync"; 5 | export * from "./debug"; 6 | export * from "./refresh"; 7 | export * from "./safeCall"; 8 | export * from "./scheduler"; 9 | export * from "./fiberType"; 10 | export * from "./isSameType"; 11 | export * from "./elementType"; 12 | export * from "./fiberToList"; 13 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/share/map.ts: -------------------------------------------------------------------------------- 1 | export const MyWeakMap = typeof WeakMap !== "undefined" ? WeakMap : Map; 2 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/src/share/sync.ts: -------------------------------------------------------------------------------- 1 | import { __my_react_shared__ } from "@my-react/react"; 2 | 3 | const { enableSyncFlush } = __my_react_shared__; 4 | 5 | /** 6 | * @deprecated 7 | */ 8 | export let syncFlush = false; 9 | 10 | /** 11 | * @deprecated 12 | */ 13 | export const beforeSyncFlush = () => { 14 | syncFlush = true; 15 | }; 16 | 17 | /** 18 | * @deprecated 19 | */ 20 | export const afterSyncFlush = () => { 21 | syncFlush = false; 22 | }; 23 | 24 | const stack = [enableSyncFlush.current]; 25 | 26 | export const beforeSyncUpdate = () => { 27 | stack.push(enableSyncFlush.current); 28 | 29 | enableSyncFlush.current = true; 30 | }; 31 | 32 | export const afterSyncUpdate = () => { 33 | enableSyncFlush.current = stack.pop(); 34 | }; 35 | -------------------------------------------------------------------------------- /packages/myreact-reconciler/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "target": "ES5", 5 | "esModuleInterop": true 6 | }, 7 | "include": ["./src"], 8 | "exclude": ["node_modules"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/myreact-refresh-tools/RefreshWebpackPlugin.d.ts: -------------------------------------------------------------------------------- 1 | export * from "./dist/types/webpackPlugin"; 2 | -------------------------------------------------------------------------------- /packages/myreact-refresh-tools/RefreshWebpackPlugin.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | if (process.env.NODE_ENV === "production") { 4 | module.exports = require("./dist/cjs/webpackPlugin.production"); 5 | } else { 6 | module.exports = require("./dist/cjs/webpackPlugin.development"); 7 | } 8 | -------------------------------------------------------------------------------- /packages/myreact-refresh-tools/loader.d.ts: -------------------------------------------------------------------------------- 1 | export * from "./dist/types/loader"; 2 | -------------------------------------------------------------------------------- /packages/myreact-refresh-tools/loader.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | if (process.env.NODE_ENV === "production") { 4 | module.exports = require("./dist/cjs/loader.production"); 5 | } else { 6 | module.exports = require("./dist/cjs/loader.development"); 7 | } 8 | -------------------------------------------------------------------------------- /packages/myreact-refresh-tools/readme.md: -------------------------------------------------------------------------------- 1 | ## copy from next.js 2 | 3 | SEE https://github.com/vercel/next.js/tree/canary/packages/react-refresh-utils 4 | -------------------------------------------------------------------------------- /packages/myreact-refresh-tools/runtime.d.ts: -------------------------------------------------------------------------------- 1 | export * from "./dist/types/runtime"; 2 | -------------------------------------------------------------------------------- /packages/myreact-refresh-tools/runtime.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | if (process.env.NODE_ENV === "production") { 4 | module.exports = require("./dist/cjs/runtime.production"); 5 | } else { 6 | module.exports = require("./dist/cjs/runtime.development"); 7 | } 8 | -------------------------------------------------------------------------------- /packages/myreact-refresh-tools/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "target": "ES6", 5 | "esModuleInterop": true, 6 | "moduleResolution": "Node" 7 | }, 8 | "include": ["./src"], 9 | "exclude": ["node_modules"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/myreact-refresh/babel.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | if (process.env.NODE_ENV === "production") { 4 | module.exports = require("./dist/cjs/RefreshBabelPlugin.production"); 5 | } else { 6 | module.exports = require("./dist/cjs/RefreshBabelPlugin.development"); 7 | } 8 | -------------------------------------------------------------------------------- /packages/myreact-refresh/readme.md: -------------------------------------------------------------------------------- 1 | ### implement @my-react/react-refresh 2 | 3 | this package just for fast refresh 4 | -------------------------------------------------------------------------------- /packages/myreact-refresh/runtime.d.ts: -------------------------------------------------------------------------------- 1 | import * as GlobalRuntime from "./dist/types/RefreshRuntime"; 2 | 3 | export default GlobalRuntime; 4 | -------------------------------------------------------------------------------- /packages/myreact-refresh/runtime.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | if (process.env.NODE_ENV === "production") { 4 | module.exports = require("./dist/cjs/RefreshRuntime.production"); 5 | } else { 6 | module.exports = require("./dist/cjs/RefreshRuntime.development"); 7 | } 8 | -------------------------------------------------------------------------------- /packages/myreact-refresh/src/global.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | const __DEV__: boolean; 3 | const __VERSION__: string; 4 | 5 | namespace NodeJS { 6 | interface ProcessEnv { 7 | NODE_ENV: "development" | "production" | "test"; 8 | } 9 | } 10 | } 11 | 12 | export {}; 13 | -------------------------------------------------------------------------------- /packages/myreact-refresh/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "target": "ES5", 5 | "esModuleInterop": true 6 | }, 7 | "include": ["./src"], 8 | "exclude": ["node_modules"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/myreact-rspack/.gitignore: -------------------------------------------------------------------------------- 1 | tsconfig.build.tsbuildinfo -------------------------------------------------------------------------------- /packages/myreact-rspack/client/overlay/components/Spacer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @typedef {Object} SpacerProps 3 | * @property {string} space 4 | */ 5 | 6 | /** 7 | * An empty element to add spacing manually. 8 | * @param {Document} document 9 | * @param {HTMLElement} root 10 | * @param {SpacerProps} props 11 | * @returns {void} 12 | */ 13 | function Spacer(document, root, props) { 14 | const spacer = document.createElement('div'); 15 | spacer.style.paddingBottom = props.space; 16 | root.appendChild(spacer); 17 | } 18 | 19 | module.exports = Spacer; -------------------------------------------------------------------------------- /packages/myreact-rspack/client/utils/retry.js: -------------------------------------------------------------------------------- 1 | function runWithRetry(callback, maxRetries) { 2 | function executeWithRetryAndTimeout(currentCount) { 3 | try { 4 | if (currentCount > maxRetries - 1) { 5 | console.warn('[React Refresh] Failed to set up the socket connection.'); 6 | return; 7 | } 8 | 9 | callback(); 10 | } catch (err) { 11 | setTimeout( 12 | function () { 13 | executeWithRetryAndTimeout(currentCount + 1); 14 | }, 15 | Math.pow(10, currentCount), 16 | ); 17 | } 18 | } 19 | 20 | executeWithRetryAndTimeout(0); 21 | } 22 | 23 | module.exports = runWithRetry; -------------------------------------------------------------------------------- /packages/myreact-rspack/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from './dist/index' -------------------------------------------------------------------------------- /packages/myreact-rspack/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./dist/index.js'); -------------------------------------------------------------------------------- /packages/myreact-rspack/overlay.js: -------------------------------------------------------------------------------- 1 | module.exports = require("./client/overlay/index"); 2 | -------------------------------------------------------------------------------- /packages/myreact-rspack/react-refresh-entry.js: -------------------------------------------------------------------------------- 1 | module.exports = require("./client/reactRefreshEntry"); 2 | -------------------------------------------------------------------------------- /packages/myreact-rspack/react-refresh.js: -------------------------------------------------------------------------------- 1 | module.exports = require("./client/reactRefresh"); 2 | -------------------------------------------------------------------------------- /packages/myreact-rspack/readme.md: -------------------------------------------------------------------------------- 1 | ## copy from rspack-plugin-react-refresh 2 | 3 | SEE https://github.com/rspack-contrib/rspack-plugin-react-refresh 4 | -------------------------------------------------------------------------------- /packages/myreact-rspack/src/global.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | namespace NodeJS { 3 | interface ProcessEnv { 4 | NODE_ENV: "development" | "production" | "test"; 5 | } 6 | } 7 | } 8 | 9 | export {}; 10 | -------------------------------------------------------------------------------- /packages/myreact-rspack/src/paths.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | 3 | export const reactRefreshPath = require.resolve('../client/reactRefresh.js'); 4 | export const reactRefreshEntryPath = require.resolve( 5 | '../client/reactRefreshEntry.js', 6 | ); 7 | export const refreshUtilsPath = require.resolve('../client/refreshUtils.js'); 8 | export const refreshRuntimeDirPath = path.dirname( 9 | require.resolve('@my-react/react-refresh', { 10 | paths: [reactRefreshPath], 11 | }), 12 | ); 13 | export const runtimePaths = [ 14 | reactRefreshEntryPath, 15 | reactRefreshPath, 16 | refreshUtilsPath, 17 | refreshRuntimeDirPath, 18 | ]; -------------------------------------------------------------------------------- /packages/myreact-rspack/src/utils/getIntegrationEntry.ts: -------------------------------------------------------------------------------- 1 | import type { IntegrationType } from './getSocketIntegration'; 2 | 3 | /** 4 | * Gets entry point of a supported socket integration. 5 | * @param integrationType A valid socket integration type or a path to a module. 6 | * @returns Path to the resolved integration entry point. 7 | */ 8 | export function getIntegrationEntry(integrationType: IntegrationType) { 9 | let resolvedEntry: string | undefined; 10 | switch (integrationType) { 11 | case 'whm': { 12 | resolvedEntry = 'webpack-hot-middleware/client'; 13 | break; 14 | } 15 | } 16 | 17 | return resolvedEntry; 18 | } -------------------------------------------------------------------------------- /packages/myreact-rspack/src/utils/getSocketIntegration.ts: -------------------------------------------------------------------------------- 1 | export type IntegrationType = 'wds' | 'whm' | (string & {}); 2 | 3 | export function getSocketIntegration(integrationType: IntegrationType) { 4 | let resolvedSocketIntegration: string; 5 | switch (integrationType) { 6 | case 'wds': { 7 | resolvedSocketIntegration = require.resolve('../sockets/WDSSocket'); 8 | break; 9 | } 10 | case 'whm': { 11 | resolvedSocketIntegration = require.resolve('../sockets/WHMEventSource'); 12 | break; 13 | } 14 | default: { 15 | resolvedSocketIntegration = require.resolve(integrationType); 16 | break; 17 | } 18 | } 19 | 20 | return resolvedSocketIntegration; 21 | } -------------------------------------------------------------------------------- /packages/myreact-rspack/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "sourceMap": false, 5 | "declarationMap": false 6 | } 7 | } -------------------------------------------------------------------------------- /packages/myreact-rspack/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "NodeNext", 4 | "moduleResolution": "NodeNext", 5 | "target": "ES2021", 6 | "esModuleInterop": true, 7 | "declaration": true, 8 | "isolatedModules": true, 9 | "sourceMap": true, 10 | "declarationMap": true, 11 | "composite": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "allowJs": true, 14 | "checkJs": true, 15 | "strict": true, 16 | "skipLibCheck": true, 17 | "noUnusedLocals": true, 18 | "outDir": "dist", 19 | "rootDir": "src" 20 | }, 21 | "include": ["src"] 22 | } -------------------------------------------------------------------------------- /packages/myreact-shared/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from "./dist/types"; 2 | -------------------------------------------------------------------------------- /packages/myreact-shared/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | if (process.env.NODE_ENV === "production") { 4 | module.exports = require("./dist/cjs/index.production"); 5 | } else { 6 | module.exports = require("./dist/cjs/index.development"); 7 | } 8 | -------------------------------------------------------------------------------- /packages/myreact-shared/src/bit.ts: -------------------------------------------------------------------------------- 1 | export const merge = (src: number, rest: number) => { 2 | return src | rest; 3 | }; 4 | 5 | export const remove = (src: number, rest: number) => { 6 | if (src & rest) { 7 | return src ^ rest; 8 | } else { 9 | return src; 10 | } 11 | }; 12 | 13 | export const include = (src: number, rest: number) => { 14 | return !!(src & rest); 15 | }; 16 | 17 | export const exclude = (src: number, rest: number) => { 18 | return !(src & rest); 19 | }; 20 | -------------------------------------------------------------------------------- /packages/myreact-shared/src/global.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | const __DEV__: boolean; 3 | const __VERSION__: string; 4 | 5 | namespace NodeJS { 6 | interface ProcessEnv { 7 | NODE_ENV: "development" | "production" | "test"; 8 | } 9 | } 10 | } 11 | 12 | export {}; 13 | -------------------------------------------------------------------------------- /packages/myreact-shared/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./bit"; 2 | export * from "./once"; 3 | export * from "./type"; 4 | export * from "./tools"; 5 | export * from "./array"; 6 | export * from "./symbol"; 7 | export * from "./version"; 8 | export * from "./isEquals"; 9 | export * from "./listTree"; 10 | -------------------------------------------------------------------------------- /packages/myreact-shared/src/once.ts: -------------------------------------------------------------------------------- 1 | export const once = (action: (...args: T) => K) => { 2 | let called = false; 3 | 4 | return (...args: T) => { 5 | if (called) return; 6 | 7 | called = true; 8 | 9 | if (typeof action === "function") action.call(null, ...args); 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /packages/myreact-shared/src/symbol/fiberPatch.ts: -------------------------------------------------------------------------------- 1 | export enum PATCH_TYPE { 2 | __initial__ = 0, 3 | __create__ = 1 << 0, 4 | __update__ = 1 << 1, 5 | __append__ = 1 << 2, 6 | __position__ = 1 << 3, 7 | __effect__ = 1 << 4, 8 | __layoutEffect__ = 1 << 5, 9 | __insertionEffect__ = 1 << 6, 10 | __unmount__ = 1 << 7, 11 | __ref__ = 1 << 8, 12 | } 13 | -------------------------------------------------------------------------------- /packages/myreact-shared/src/symbol/fiberState.ts: -------------------------------------------------------------------------------- 1 | export enum STATE_TYPE { 2 | __initial__ = 0, 3 | __create__ = 1 << 0, 4 | __stable__ = 1 << 1, 5 | __skippedConcurrent__ = 1 << 2, 6 | __skippedSync__ = 1 << 3, 7 | __inherit__ = 1 << 4, 8 | __triggerConcurrent__ = 1 << 5, 9 | __triggerConcurrentForce__ = 1 << 6, 10 | __triggerSync__ = 1 << 7, 11 | __triggerSyncForce__ = 1 << 8, 12 | __unmount__ = 1 << 9, 13 | __hmr__ = 1 << 10, 14 | __retrigger__ = 1 << 11, 15 | __reschedule__ = 1 << 12 16 | } 17 | -------------------------------------------------------------------------------- /packages/myreact-shared/src/symbol/hookType.ts: -------------------------------------------------------------------------------- 1 | export enum HOOK_TYPE { 2 | useId = 0, 3 | useRef = 1, 4 | useMemo = 2, 5 | useState = 3, 6 | useSignal = 4, 7 | useEffect = 5, 8 | useContext = 6, 9 | useReducer = 7, 10 | useCallback = 8, 11 | useTransition = 9, 12 | useDebugValue = 10, 13 | useLayoutEffect = 11, 14 | useDeferredValue = 12, 15 | useInsertionEffect = 13, 16 | useImperativeHandle = 14, 17 | useSyncExternalStore = 15, 18 | } 19 | -------------------------------------------------------------------------------- /packages/myreact-shared/src/symbol/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./hookType"; 2 | export * from "./queueType"; 3 | export * from "./fiberState"; 4 | export * from "./fiberPatch"; 5 | export * from "./instanceEffect"; 6 | -------------------------------------------------------------------------------- /packages/myreact-shared/src/symbol/instanceEffect.ts: -------------------------------------------------------------------------------- 1 | export enum Effect_TYPE { 2 | __initial__ = 0, 3 | __effect__ = 1 << 0, 4 | __unmount__ = 1 << 1, 5 | } 6 | -------------------------------------------------------------------------------- /packages/myreact-shared/src/symbol/queueType.ts: -------------------------------------------------------------------------------- 1 | export enum UpdateQueueType { 2 | component = 1, 3 | hook = 2, 4 | context = 3, 5 | hmr = 4, 6 | trigger = 5, 7 | suspense = 6, 8 | 9 | } 10 | -------------------------------------------------------------------------------- /packages/myreact-shared/src/version.ts: -------------------------------------------------------------------------------- 1 | export const compareVersion = (version1: string, version2: string) => { 2 | const compare = (arr1: number[], arr2: number[]) => { 3 | if (arr1.length && arr2.length) { 4 | const v1 = arr1[0]; 5 | const v2 = arr2[0]; 6 | if (v1 > v2) return true; 7 | if (v2 > v1) return false; 8 | return compare(arr1.slice(1), arr2.slice(1)); 9 | } 10 | if (arr1.length) return true; 11 | if (arr2.length) return false; 12 | return true; 13 | }; 14 | 15 | return compare(version1.split(".").map(Number), version2.split(".").map(Number)); 16 | }; 17 | -------------------------------------------------------------------------------- /packages/myreact-shared/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "target": "ES5" 5 | }, 6 | "include": ["./src"], 7 | "exclude": ["node_modules"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/myreact-terminal/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from "./dist/types"; 2 | -------------------------------------------------------------------------------- /packages/myreact-terminal/index.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-useless-path-segments */ 2 | export * from "./dist/esm/index.mjs"; -------------------------------------------------------------------------------- /packages/myreact-terminal/readme.md: -------------------------------------------------------------------------------- 1 | ## copy from ink 2 | 3 | SEE https://github.com/vadimdemedes/ink 4 | -------------------------------------------------------------------------------- /packages/myreact-terminal/src/components/AppContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from "react"; 2 | 3 | export type Props = { 4 | /** 5 | * Exit (unmount) the whole Ink app. 6 | */ 7 | readonly exit: (error?: Error) => void; 8 | }; 9 | 10 | /** 11 | * `AppContext` is a React context, which exposes a method to manually exit the app (unmount). 12 | */ 13 | const AppContext = createContext({ 14 | exit() {}, 15 | }); 16 | 17 | AppContext.displayName = "InternalAppContext"; 18 | 19 | export default AppContext; 20 | -------------------------------------------------------------------------------- /packages/myreact-terminal/src/components/Newline.tsx: -------------------------------------------------------------------------------- 1 | export type Props = { 2 | /** 3 | * Number of newlines to insert. 4 | * 5 | * @default 1 6 | */ 7 | readonly count?: number; 8 | }; 9 | 10 | /** 11 | * Adds one or more newline (\n) characters. Must be used within components. 12 | */ 13 | export default function Newline({count = 1}: Props) { 14 | return {'\n'.repeat(count)}; 15 | } 16 | -------------------------------------------------------------------------------- /packages/myreact-terminal/src/components/Spacer.tsx: -------------------------------------------------------------------------------- 1 | import Box from "./Box"; 2 | 3 | /** 4 | * A flexible space that expands along the major axis of its containing layout. 5 | * It's useful as a shortcut for filling all the available spaces between elements. 6 | */ 7 | export default function Spacer() { 8 | return ; 9 | } 10 | -------------------------------------------------------------------------------- /packages/myreact-terminal/src/get-max-width.ts: -------------------------------------------------------------------------------- 1 | import Yoga, { type Node as YogaNode } from "yoga-layout"; 2 | 3 | const getMaxWidth = (yogaNode: YogaNode) => { 4 | return ( 5 | yogaNode.getComputedWidth() - 6 | yogaNode.getComputedPadding(Yoga.EDGE_LEFT) - 7 | yogaNode.getComputedPadding(Yoga.EDGE_RIGHT) - 8 | yogaNode.getComputedBorder(Yoga.EDGE_LEFT) - 9 | yogaNode.getComputedBorder(Yoga.EDGE_RIGHT) 10 | ); 11 | }; 12 | 13 | export default getMaxWidth; 14 | -------------------------------------------------------------------------------- /packages/myreact-terminal/src/hooks/use-app.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | 3 | import AppContext from '../components/AppContext'; 4 | 5 | /** 6 | * `useApp` is a React hook, which exposes a method to manually exit the app (unmount). 7 | */ 8 | const useApp = () => useContext(AppContext); 9 | export default useApp; 10 | -------------------------------------------------------------------------------- /packages/myreact-terminal/src/hooks/use-stderr.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from "react"; 2 | 3 | import StderrContext from "../components/StderrContext"; 4 | 5 | /** 6 | * `useStderr` is a React hook, which exposes stderr stream. 7 | */ 8 | const useStderr = () => useContext(StderrContext); 9 | export default useStderr; 10 | -------------------------------------------------------------------------------- /packages/myreact-terminal/src/hooks/use-stdin.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from "react"; 2 | 3 | import StdinContext from "../components/StdinContext"; 4 | 5 | /** 6 | * `useStdin` is a React hook, which exposes stdin stream. 7 | */ 8 | const useStdin = () => useContext(StdinContext); 9 | export default useStdin; 10 | -------------------------------------------------------------------------------- /packages/myreact-terminal/src/hooks/use-stdout.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from "react"; 2 | 3 | import StdoutContext from "../components/StdoutContext"; 4 | 5 | /** 6 | * `useStdout` is a React hook, which exposes stdout stream. 7 | */ 8 | const useStdout = () => useContext(StdoutContext); 9 | export default useStdout; 10 | -------------------------------------------------------------------------------- /packages/myreact-terminal/src/instances.ts: -------------------------------------------------------------------------------- 1 | // Store all instances of Ink (instance.js) to ensure that consecutive render() calls 2 | // use the same instance of Ink and don't create a new one 3 | // 4 | // This map has to be stored in a separate file, because render.js creates instances, 5 | // but instance.js should delete itself from the map on unmount 6 | 7 | import type Ink from "./ink"; 8 | 9 | const instances = new WeakMap(); 10 | export default instances; 11 | -------------------------------------------------------------------------------- /packages/myreact-terminal/src/measure-element.ts: -------------------------------------------------------------------------------- 1 | import { type DOMElement } from "./dom"; 2 | 3 | type Output = { 4 | /** 5 | * Element width. 6 | */ 7 | width: number; 8 | 9 | /** 10 | * Element height. 11 | */ 12 | height: number; 13 | }; 14 | 15 | /** 16 | * Measure the dimensions of a particular `` element. 17 | */ 18 | const measureElement = (node: DOMElement): Output => ({ 19 | width: node.yogaNode?.getComputedWidth() ?? 0, 20 | height: node.yogaNode?.getComputedHeight() ?? 0, 21 | }); 22 | 23 | export default measureElement; 24 | -------------------------------------------------------------------------------- /packages/myreact-terminal/src/measure-text.ts: -------------------------------------------------------------------------------- 1 | import widestLine from "widest-line"; 2 | 3 | const cache: Record = {}; 4 | 5 | type Output = { 6 | width: number; 7 | height: number; 8 | }; 9 | 10 | const measureText = (text: string): Output => { 11 | if (text.length === 0) { 12 | return { 13 | width: 0, 14 | height: 0, 15 | }; 16 | } 17 | 18 | const cachedDimensions = cache[text]; 19 | 20 | if (cachedDimensions) { 21 | return cachedDimensions; 22 | } 23 | 24 | const width = widestLine(text); 25 | const height = text.split("\n").length; 26 | cache[text] = { width, height }; 27 | 28 | return { width, height }; 29 | }; 30 | 31 | export default measureText; 32 | -------------------------------------------------------------------------------- /packages/myreact-terminal/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "target": "ESNext", 5 | "module": "ESNext", 6 | "esModuleInterop": true, 7 | "moduleResolution": "Bundler", 8 | "jsx": "react-jsx", 9 | "jsxImportSource": "@my-react/react-jsx" 10 | }, 11 | "include": ["./src"], 12 | "exclude": ["node_modules"] 13 | } -------------------------------------------------------------------------------- /packages/myreact-three-fiber/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from "./dist/types"; 2 | -------------------------------------------------------------------------------- /packages/myreact-three-fiber/index.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-useless-path-segments */ 2 | // check pkg alias 3 | import React from "react"; 4 | 5 | if (!React.isMyReact) { 6 | throw new Error( 7 | "@my-react/react-three-fiber requires 'React' to be set as '@my-react/react'. Please ensure you have set the alias correctly in your bundler configuration." 8 | ); 9 | } 10 | 11 | export * from "./dist/esm/index.mjs"; 12 | -------------------------------------------------------------------------------- /packages/myreact-three-fiber/readme.md: -------------------------------------------------------------------------------- 1 | ## copy from react-three-fiber 2 | 3 | SEE https://github.com/pmndrs/react-three-fiber 4 | -------------------------------------------------------------------------------- /packages/myreact-three-fiber/src/index.tsx: -------------------------------------------------------------------------------- 1 | import * as ReactThreeFiber from "./three-types"; 2 | 3 | export { ReactThreeFiber }; 4 | export * from "./three-types"; 5 | export * from "./core"; 6 | export * from "./web/Canvas"; 7 | export { createPointerEvents as events } from "./web/events"; 8 | -------------------------------------------------------------------------------- /packages/myreact-three-fiber/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "target": "ESNext", 5 | "module": "ESNext", 6 | "esModuleInterop": true, 7 | "moduleResolution": "Bundler", 8 | "jsx": "react-jsx", 9 | "jsxImportSource": "@my-react/react-jsx" 10 | }, 11 | "include": ["./src"], 12 | "exclude": ["node_modules"] 13 | } -------------------------------------------------------------------------------- /packages/myreact-vite/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | if (process.env.NODE_ENV === "production") { 4 | module.exports = require("./dist/cjs/index.production"); 5 | } else { 6 | module.exports = require("./dist/cjs/index.development"); 7 | } 8 | -------------------------------------------------------------------------------- /packages/myreact-vite/readme.md: -------------------------------------------------------------------------------- 1 | ## copy from vite-plugin-react 2 | 3 | SEE https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react 4 | -------------------------------------------------------------------------------- /packages/myreact-vite/refreshUtils.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | if (process.env.NODE_ENV === "production") { 4 | module.exports = require("./dist/cjs/refreshUtils.production"); 5 | } else { 6 | module.exports = require("./dist/cjs/refreshUtils.development"); 7 | } 8 | -------------------------------------------------------------------------------- /packages/myreact-vite/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "target": "ES2020", 5 | "module": "ES2020", 6 | "moduleResolution": "Node", 7 | "strict": true, 8 | "noUnusedLocals": true, 9 | "esModuleInterop": true 10 | }, 11 | "include": ["./src"], 12 | "exclude": ["node_modules"] 13 | } 14 | -------------------------------------------------------------------------------- /packages/myreact/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | if (process.env.NODE_ENV === "production") { 4 | module.exports = require("./dist/cjs/index.production"); 5 | } else { 6 | module.exports = require("./dist/cjs/index.development"); 7 | } 8 | -------------------------------------------------------------------------------- /packages/myreact/jsx-dev-runtime.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = require("@my-react/react-jsx"); 4 | -------------------------------------------------------------------------------- /packages/myreact/jsx-runtime.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = require("@my-react/react-jsx"); 4 | -------------------------------------------------------------------------------- /packages/myreact/readme.md: -------------------------------------------------------------------------------- 1 | ## @my-react/react 2 | 3 | this is a react like package, for usage see https://mrwangjusttodo.github.io/MyReact/ which build by @my-react 4 | 5 | ```shell 6 | pnpm add @my-react/react 7 | ``` 8 | -------------------------------------------------------------------------------- /packages/myreact/src/children/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact/src/component/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./instance"; 2 | -------------------------------------------------------------------------------- /packages/myreact/src/element/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./tool"; 2 | export * from "./feature"; 3 | export * from "./instance"; 4 | -------------------------------------------------------------------------------- /packages/myreact/src/global.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | const __DEV__: boolean; 3 | const __VERSION__: string; 4 | 5 | const scheduler: any; 6 | 7 | namespace NodeJS { 8 | interface ProcessEnv { 9 | NODE_ENV: "development" | "production" | "test"; 10 | } 11 | } 12 | } 13 | 14 | export {}; 15 | -------------------------------------------------------------------------------- /packages/myreact/src/hook/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | -------------------------------------------------------------------------------- /packages/myreact/src/internal/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./instance"; 2 | -------------------------------------------------------------------------------- /packages/myreact/src/internal/instance.ts: -------------------------------------------------------------------------------- 1 | import type { RenderFiber } from "../renderFiber"; 2 | 3 | /** 4 | * @public 5 | */ 6 | export class MyReactInternalInstance { 7 | get isMyReactInstance() { 8 | return true; 9 | } 10 | _reactInternals: RenderFiber; 11 | } 12 | -------------------------------------------------------------------------------- /packages/myreact/src/renderFiber/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./interface"; 2 | -------------------------------------------------------------------------------- /packages/myreact/src/renderHook/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./interface"; 2 | -------------------------------------------------------------------------------- /packages/myreact/src/renderQueue/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./interface"; 2 | -------------------------------------------------------------------------------- /packages/myreact/src/renderScheduler/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./feature"; 2 | export * from "./interface"; 3 | -------------------------------------------------------------------------------- /packages/myreact/src/share/cache.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type 2 | export const cache = (fn: T) => { 3 | return fn(); 4 | } -------------------------------------------------------------------------------- /packages/myreact/src/share/createRef.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @public 3 | */ 4 | export const createRef = (value: T) => { 5 | const refValue = { current: value }; 6 | 7 | if (__DEV__ && typeof Object.seal === "function") Object.seal(refValue); 8 | 9 | return refValue; 10 | }; 11 | 12 | /** 13 | * @internal 14 | */ 15 | export const createReadonlyRef = (value: T) => { 16 | const refValue = { current: value, readonly: true }; 17 | 18 | if (typeof Object.freeze === "function") Object.freeze(refValue); 19 | 20 | return refValue; 21 | }; 22 | -------------------------------------------------------------------------------- /packages/myreact/src/share/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./env"; 2 | export * from "./task"; 3 | export * from "./hook"; 4 | export * from "./cache"; 5 | export * from "./dispatch"; 6 | export * from "./createRef"; 7 | export * from "./transition"; 8 | -------------------------------------------------------------------------------- /packages/myreact/src/share/transition.ts: -------------------------------------------------------------------------------- 1 | import { currentScheduler } from "./env"; 2 | 3 | /** 4 | * @public 5 | */ 6 | export const startTransition = (cb: () => void) => { 7 | if (currentScheduler.current) { 8 | currentScheduler.current.yieldTask(cb); 9 | } else { 10 | cb(); 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /packages/myreact/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "target": "ES5", 5 | "stripInternal": true 6 | }, 7 | "include": ["./src"], 8 | "exclude": ["node_modules"] 9 | } 10 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - "packages/*" 3 | - "ui/*" 4 | - "test/*" 5 | - "site/*" 6 | - "site/!lib" 7 | -------------------------------------------------------------------------------- /scripts/rollupTerminal.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-unused-vars */ 2 | import { rollupBuild, rollupWatch } from "project-tool/rollup"; 3 | 4 | export const externalReact = (id: string) => 5 | id.endsWith("@my-react/react") || 6 | id.endsWith("@my-react/react-dom") || 7 | id.includes("@my-react/react-refresh") || 8 | id.endsWith("@my-react/react-terminal") || 9 | (id.includes("node_modules") && !id.includes("tslib")); 10 | 11 | const build = async () => { 12 | await rollupBuild({ packageName: "terminal", packageScope: "test", external: externalReact }); 13 | }; 14 | 15 | const watch = () => { 16 | rollupWatch({ packageName: "terminal", packageScope: "test", external: externalReact }); 17 | }; 18 | 19 | build(); 20 | 21 | // watch(); -------------------------------------------------------------------------------- /scripts/rollupWatch.ts: -------------------------------------------------------------------------------- 1 | import { rollupWatch } from "project-tool/rollup"; 2 | 3 | export const externalReact = (id: string) => 4 | id.endsWith("@my-react/react") || 5 | id.endsWith("@my-react/react-dom") || 6 | id.includes("@my-react/react-refresh") || 7 | id.endsWith("@my-react/react-terminal") || 8 | (id.includes("node_modules") && !id.includes("tslib")); 9 | 10 | rollupWatch({ packageName: "myreact-reconciler", packageScope: "packages", external: externalReact }); 11 | rollupWatch({ packageName: "myreact-terminal", packageScope: "packages", external: externalReact }); 12 | 13 | // rollupWatch({ packageName: "myreact-dom", packageScope: "packages", external }); 14 | -------------------------------------------------------------------------------- /scripts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "module": "CommonJS" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /site/graphql/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["plugin:react/recommended", "plugin:react-hooks/recommended", "../../.eslintrc.js"], 3 | settings: { 4 | react: { 5 | version: "detect", // React version. "detect" automatically picks the version you have installed. 6 | }, 7 | }, 8 | parserOptions: { 9 | ecmaFeatures: { 10 | jsx: true, 11 | }, 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /site/graphql/env.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | const __DEV__: boolean; 3 | namespace NodeJS { 4 | interface ProcessEnv { 5 | NODE_ENV: "development" | "production" | "test"; 6 | NEXT_PUBLIC_TOKEN: string; 7 | } 8 | } 9 | } 10 | 11 | export {}; 12 | -------------------------------------------------------------------------------- /site/graphql/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | if (process.env.NODE_ENV === "production") { 4 | module.exports = require("./dist/cjs/index.production"); 5 | } else { 6 | module.exports = require("./dist/cjs/index.development"); 7 | } 8 | -------------------------------------------------------------------------------- /site/graphql/src/apollo/index.ts: -------------------------------------------------------------------------------- 1 | export { getApolloClient, useApollo } from "./client"; 2 | -------------------------------------------------------------------------------- /site/graphql/src/document/auth.graphql: -------------------------------------------------------------------------------- 1 | query getViewer($first: Int = 10) { 2 | viewer { 3 | id 4 | name 5 | login 6 | email 7 | createdAt 8 | avatarUrl 9 | websiteUrl 10 | projectsUrl 11 | followers(first: $first) { 12 | nodes { 13 | id 14 | name 15 | login 16 | email 17 | bioHTML 18 | avatarUrl 19 | } 20 | } 21 | following(first: $first) { 22 | nodes { 23 | id 24 | name 25 | login 26 | email 27 | bioHTML 28 | avatarUrl 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /site/graphql/src/document/repo.graphql: -------------------------------------------------------------------------------- 1 | query getRepoAbout($name: String!, $owner: String!) { 2 | repository(name: $name, owner: $owner) { 3 | description 4 | url 5 | homepageUrl 6 | descriptionHTML 7 | stargazerCount 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /site/graphql/src/document/star.graphql: -------------------------------------------------------------------------------- 1 | query getStarCount($name: String!, $owner: String!) { 2 | repository(name: $name, owner: $owner) { 3 | id 4 | stargazerCount 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /site/graphql/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./apollo"; 2 | export * from "./generated"; 3 | export * from "./schema"; 4 | -------------------------------------------------------------------------------- /site/graphql/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "target": "ES5", 5 | "allowSyntheticDefaultImports": true 6 | }, 7 | "include": ["./src"], 8 | "exclude": ["node_modules"] 9 | } 10 | -------------------------------------------------------------------------------- /site/lib/build/getCommonJSDeps.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const regex1 = /require\s*\(\s*(['|"])(.*?)\1\s*\)\s*/g; 3 | const regex2 = /require\s*\(\s*(['|"])(.*?)\1\s*\)\s*/; 4 | 5 | const getCommonJSDeps = (content, fullPath) => { 6 | const all = content.match(regex1) || []; 7 | const dirname = path.dirname(fullPath); 8 | return all.map((moduleName) => { 9 | const entry = regex2.exec(moduleName)[2]; 10 | const fullPath = path.resolve(dirname, entry); 11 | return { entry, fullPath }; 12 | }); 13 | }; 14 | 15 | module.exports.getCommonJSDeps = getCommonJSDeps; 16 | -------------------------------------------------------------------------------- /site/lib/build/getFileContent.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | 3 | const getFileContent = async (filePath) => { 4 | return await fs.promises.readFile(filePath, { 5 | encoding: "utf-8", 6 | }); 7 | }; 8 | 9 | module.exports.getFileContent = getFileContent; 10 | -------------------------------------------------------------------------------- /site/lib/build/index.js: -------------------------------------------------------------------------------- 1 | // tiny webpack tools 2 | const { commonJSBootStrap } = require("./bootStrap"); 3 | 4 | // build 5 | commonJSBootStrap("../redux/redux.js", "../../../reduxBundle.js") 6 | .then(() => commonJSBootStrap("../redux/reactRedux.js", "../../../reactReduxBundle.js")) 7 | .then(() => commonJSBootStrap("../redux/thunk.js", "../../../thunkBundle.js")) 8 | .then(() => commonJSBootStrap("../zustand/react.js", "../../../zustandBundle.js")) 9 | .then(() => commonJSBootStrap("../redux/toolkit.js", "../../../reduxToolKitBundle.js")); 10 | -------------------------------------------------------------------------------- /site/lib/build/writeFileContent.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | 3 | const writeFileContent = async (content, output) => await fs.promises.writeFile(output, content); 4 | 5 | module.exports.writeFileContent = writeFileContent; 6 | -------------------------------------------------------------------------------- /site/lib/redux/log.js: -------------------------------------------------------------------------------- 1 | const logMiddleware = (store) => (next) => (action) => { 2 | const beforeState = store.getState(); 3 | next(action); 4 | const afterState = store.getState(); 5 | console.log({ beforeState, action, afterState }); 6 | }; 7 | 8 | window.log = logMiddleware; 9 | 10 | module.exports.log = logMiddleware; 11 | -------------------------------------------------------------------------------- /site/lib/redux/thunk.js: -------------------------------------------------------------------------------- 1 | const thunkMiddleware = (store) => (next) => (action) => { 2 | if (typeof action === "function") { 3 | action(store.dispatch, store); 4 | } else { 5 | next(action); 6 | } 7 | }; 8 | 9 | window.thunk = thunkMiddleware; 10 | 11 | module.exports.thunkMiddleware = thunkMiddleware; 12 | -------------------------------------------------------------------------------- /site/lib/zustand/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/site/lib/zustand/index.js -------------------------------------------------------------------------------- /site/webpack/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = require("./dist/cjs/index"); 4 | -------------------------------------------------------------------------------- /site/webpack/src/base/config/common.ts: -------------------------------------------------------------------------------- 1 | import path from "path"; 2 | 3 | import type { SafeGenerateActionProps } from "../type"; 4 | import type { Configuration } from "webpack"; 5 | 6 | export const commonConfig = ({ env, isDEV }: SafeGenerateActionProps): Partial => ({ 7 | name: env, 8 | mode: (isDEV ? "development" : "production") as "development" | "production", 9 | target: env === "client" ? "web" : "node16", 10 | context: path.resolve(process.cwd()), 11 | externalsPresets: env === "server" ? { node: true } : { web: true }, 12 | }); 13 | -------------------------------------------------------------------------------- /site/webpack/src/base/config/externals.ts: -------------------------------------------------------------------------------- 1 | // import nodeExternals from "webpack-node-externals"; 2 | 3 | import type { SafeGenerateActionProps } from "../type"; 4 | 5 | export const externalsConfig = ({ env }: SafeGenerateActionProps) => 6 | env === "server" 7 | ? [ 8 | // nodeExternals({ 9 | // // load non-javascript files with extensions, presumably via loaders 10 | // allowlist: [/\.(?!(?:jsx?|json)$).{1,5}$/i, "webpack/hot/poll?1000", "lodash-es"], 11 | // }), 12 | ] 13 | : {}; 14 | -------------------------------------------------------------------------------- /site/webpack/src/base/config/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./common"; 2 | export * from "./externals"; 3 | export * from "./output"; 4 | export * from "./plugins"; 5 | export * from "./statsConfig"; 6 | -------------------------------------------------------------------------------- /site/webpack/src/base/config/statsConfig.ts: -------------------------------------------------------------------------------- 1 | import type { SafeGenerateActionProps } from "../type"; 2 | import type { Configuration } from "webpack"; 3 | 4 | export const statsConfig = ({ env, isDEV }: SafeGenerateActionProps): Configuration["stats"] => { 5 | return isDEV || env === "server" ? "errors-only" : "normal"; 6 | }; 7 | -------------------------------------------------------------------------------- /site/webpack/src/base/index.ts: -------------------------------------------------------------------------------- 1 | import { config, singleConfig } from "./webpack.config"; 2 | 3 | export * from "./type"; 4 | 5 | export const definedUniversalWebpackConfig = config; 6 | 7 | export const definedWebpackConfig = singleConfig; 8 | 9 | export { MANIFEST } from "./utils"; 10 | -------------------------------------------------------------------------------- /site/webpack/src/base/utils/config.ts: -------------------------------------------------------------------------------- 1 | export enum MANIFEST { 2 | manifest_loadable = "manifest-loadable.json", 3 | manifest_deps = "manifest-deps.json", 4 | manifest_dev = "manifest-dev.json", 5 | manifest_prod = "manifest-prod.json", 6 | manifest_static = "manifest-static.json", 7 | } 8 | -------------------------------------------------------------------------------- /site/webpack/src/base/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./config"; 2 | -------------------------------------------------------------------------------- /site/webpack/src/base/webpack.base.config.ts: -------------------------------------------------------------------------------- 1 | import { commonConfig } from "./config/common"; 2 | import { statsConfig } from "./config/statsConfig"; 3 | 4 | import type { SafeGenerateActionProps } from "./type"; 5 | import type { Configuration } from "webpack"; 6 | 7 | export const BaseConfig = (props: SafeGenerateActionProps): Partial => ({ 8 | ...commonConfig(props), 9 | stats: statsConfig(props), 10 | infrastructureLogging: { 11 | level: "error" as const, 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /site/webpack/src/react/config/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./devServer"; 2 | export * from "./optimization"; 3 | export * from "./plugins"; 4 | export * from "./resolve"; 5 | export * from "./rules"; 6 | -------------------------------------------------------------------------------- /site/webpack/src/react/config/plugins.ts: -------------------------------------------------------------------------------- 1 | import MiniCssExtractPlugin from "mini-css-extract-plugin"; 2 | 3 | import type { SafeGenerateActionPropsWithReact } from ".."; 4 | import type { Configuration } from "webpack"; 5 | 6 | export const pluginsConfig = ({ env, isDEV }: SafeGenerateActionPropsWithReact): Configuration["plugins"] => 7 | [ 8 | env === "client" && 9 | new MiniCssExtractPlugin({ 10 | filename: isDEV ? "[name].css" : "[name]-[contenthash].css", 11 | chunkFilename: isDEV ? "[name]-[id].css" : "[name]-[id]-[contenthash].css", 12 | }), 13 | ].filter(Boolean) as Configuration["plugins"]; 14 | -------------------------------------------------------------------------------- /site/webpack/src/react/config/resolve.ts: -------------------------------------------------------------------------------- 1 | import type { SafeGenerateActionPropsWithReact } from ".."; 2 | import type { Configuration } from "webpack"; 3 | 4 | export const resolveConfig = ({ env }: SafeGenerateActionPropsWithReact): Configuration["resolve"] => ({ 5 | alias: { 6 | lodash: env === "client" ? "lodash-es" : "lodash", 7 | "lodash-es": env === "server" ? "lodash" : "lodash-es", 8 | }, 9 | extensions: [".ts", ".tsx", ".js", ".jsx", ".json", ".css", ".scss"], 10 | fallback: 11 | env === "client" 12 | ? { 13 | path: false, 14 | fs: false, 15 | stream: false, 16 | } 17 | : undefined, 18 | }); 19 | -------------------------------------------------------------------------------- /site/webpack/src/safeParse.ts: -------------------------------------------------------------------------------- 1 | export const safeParse = (s: string): T | null => { 2 | try { 3 | return JSON.parse(s) as T; 4 | } catch (e) { 5 | console.error(`parse error: ${(e as Error).message}`); 6 | return null; 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /site/webpack/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "target": "ES5", 5 | "allowSyntheticDefaultImports": true 6 | }, 7 | "include": ["./src"], 8 | "exclude": ["node_modules"] 9 | } 10 | -------------------------------------------------------------------------------- /test.mjs: -------------------------------------------------------------------------------- 1 | import { testBorder, testCount, testJustifyContent, testStatic, testSuspense, testTable, testInput, testFocusId, testFocus, testStderr, testDir, testGithub } from "@test/react-terminal"; 2 | 3 | // testBorder(); 4 | 5 | // testCount(); 6 | 7 | // testJustifyContent(); 8 | 9 | // testStatic(); 10 | 11 | // testSuspense(); 12 | 13 | // testTable(); 14 | 15 | // testInput(); 16 | 17 | // testFocusId(); 18 | 19 | // testFocus(); 20 | 21 | // testStderr(); 22 | 23 | // testDir(); 24 | 25 | testGithub(); -------------------------------------------------------------------------------- /test/terminal/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from "./dist/types"; 2 | -------------------------------------------------------------------------------- /test/terminal/index.mjs: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-useless-path-segments 2 | export * from "./dist/esm/index.mjs"; -------------------------------------------------------------------------------- /test/terminal/src/count.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "@my-react/react"; 2 | import { Text, render } from "@my-react/react-terminal"; 3 | 4 | function Counter() { 5 | const [counter, setCounter] = useState(0); 6 | 7 | useEffect(() => { 8 | const timer = setInterval(() => { 9 | setCounter((prevCounter) => prevCounter + 1); 10 | }, 2000); 11 | 12 | return () => { 13 | clearInterval(timer); 14 | }; 15 | }, []); 16 | 17 | return {counter} tests passed; 18 | } 19 | 20 | export const test = () => render(); 21 | -------------------------------------------------------------------------------- /test/terminal/src/focus.tsx: -------------------------------------------------------------------------------- 1 | import { Box, Text, render, useFocus } from "@my-react/react-terminal"; 2 | 3 | function Focus() { 4 | return ( 5 | 6 | 7 | Press Tab to focus next element, Shift+Tab to focus previous element, Esc to reset focus. 8 | 9 | 10 | 11 | 12 | 13 | ); 14 | } 15 | 16 | function Item({ label }) { 17 | const { isFocused } = useFocus(); 18 | return ( 19 | 20 | {label} {isFocused && (focused)} 21 | 22 | ); 23 | } 24 | 25 | export const test = () => render(); 26 | -------------------------------------------------------------------------------- /test/terminal/src/index.ts: -------------------------------------------------------------------------------- 1 | export { test as testBorder } from "./border"; 2 | export { test as testCount } from "./count"; 3 | export { test as testJustifyContent } from "./justify-content"; 4 | export { test as testStatic } from "./static"; 5 | export { test as testSuspense } from "./suspense"; 6 | export { test as testTable } from "./table"; 7 | export { test as testInput } from "./input"; 8 | export { test as testFocusId } from "./focus-id"; 9 | export { test as testFocus } from "./focus"; 10 | export { test as testStderr } from "./stderr"; 11 | export { test as testDir } from "./dir"; 12 | export { test as testGithub } from "./github"; 13 | -------------------------------------------------------------------------------- /test/terminal/src/stderr.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from "@my-react/react"; 2 | import { render, Text, useStderr } from "@my-react/react-terminal"; 3 | 4 | function Example() { 5 | const { write } = useStderr(); 6 | 7 | useEffect(() => { 8 | const timer = setInterval(() => { 9 | write("Hello from Ink to stderr\n"); 10 | }, 1000); 11 | 12 | return () => { 13 | clearInterval(timer); 14 | }; 15 | }, []); 16 | 17 | return Hello World; 18 | } 19 | 20 | export const test = () => render(); 21 | -------------------------------------------------------------------------------- /test/terminal/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "target": "ESNext", 5 | "esModuleInterop": true, 6 | "moduleResolution": "Bundler", 7 | "jsx": "react-jsx", 8 | "jsxImportSource": "@my-react/react-jsx" 9 | }, 10 | "include": ["./src"], 11 | "exclude": ["node_modules"] 12 | } -------------------------------------------------------------------------------- /test/three-fiber/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vite + @my-react 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /test/three-fiber/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/test/three-fiber/public/favicon.ico -------------------------------------------------------------------------------- /test/three-fiber/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from "react"; 2 | import { createRoot } from "react-dom/client"; 3 | 4 | import "./index.css"; 5 | import App from "./App.tsx"; 6 | 7 | createRoot(document.getElementById("root")!).render( 8 | 9 | 10 | 11 | ); 12 | -------------------------------------------------------------------------------- /test/three-fiber/src/vite.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /test/three-fiber/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ] 7 | } -------------------------------------------------------------------------------- /test/three-fiber/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 | }, 23 | "include": ["vite.config.ts"] 24 | } -------------------------------------------------------------------------------- /test/three-fiber/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from "@my-react/react-vite"; 2 | // import react from '@vitejs/plugin-react'; 3 | import { defineConfig } from "vite"; 4 | 5 | // !SEE https://github.com/vitejs/vite/issues/12738 6 | // !build will fail when using monorepo symlinks, npm install works fine, so build always fails in this case 7 | // https://vitejs.dev/config/ 8 | export default defineConfig({ 9 | plugins: [react()], 10 | }); 11 | -------------------------------------------------------------------------------- /ui/csr-example/._root/root/recover/test.exe: -------------------------------------------------------------------------------- 1 | hhhh -------------------------------------------------------------------------------- /ui/csr-example/._root/root/root/Snipaste.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/csr-example/._root/root/root/Snipaste.png -------------------------------------------------------------------------------- /ui/csr-example/._root/root/root/newFile.js: -------------------------------------------------------------------------------- 1 | const a = () => { 2 | console.log("100"); 3 | }; 4 | -------------------------------------------------------------------------------- /ui/csr-example/._root/root/root/newFile.txt: -------------------------------------------------------------------------------- 1 | this is plain txt file 2 | 3 | this project is a csr-example power by @my-react 4 | 5 | feel free to play! 6 | 7 | and welcome to create pr for this project to make it better! -------------------------------------------------------------------------------- /ui/csr-example/.env: -------------------------------------------------------------------------------- 1 | # dev env 2 | DEV_HOST=localhost 3 | DEV_PORT=9000 4 | WDS_PORT=9001 5 | PUBLIC_DEV_API_HOST=http://localhost:9000 6 | # switch render framework --> myreact | react 7 | REACT=myreact 8 | # prod env 9 | PROD_PORT=5000 10 | PROD_HOST=localhost 11 | PUBLIC_PROD_API_HOST=http://localhost:5000 12 | # entry 13 | SERVER_ENTRY=./src/server/entry.ts 14 | CLIENT_ENTRY=./src/client/entry.js 15 | -------------------------------------------------------------------------------- /ui/csr-example/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [require.resolve("project-tool/baseLint"), require.resolve("project-tool/reactLint")], 3 | env: { 4 | browser: true, 5 | es2021: true, 6 | }, 7 | parserOptions: { 8 | ecmaFeatures: { 9 | jsx: true, 10 | }, 11 | sourceType: "module", 12 | tsconfigRootDir: __dirname, 13 | project: "tsconfig.json", 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /ui/csr-example/build/scripts/build-prod.ts: -------------------------------------------------------------------------------- 1 | import dotenv from "dotenv"; 2 | 3 | import { start } from "./entry-prod"; 4 | 5 | dotenv.config(); 6 | 7 | start(); 8 | -------------------------------------------------------------------------------- /ui/csr-example/build/scripts/log.ts: -------------------------------------------------------------------------------- 1 | import { pino } from "pino"; 2 | import pretty from "pino-pretty"; 3 | 4 | export const logger = () => pino(pretty()); 5 | -------------------------------------------------------------------------------- /ui/csr-example/build/scripts/start-dev.ts: -------------------------------------------------------------------------------- 1 | import dotenv from "dotenv"; 2 | import { resolve } from "path"; 3 | 4 | import { start } from "./entry-dev"; 5 | 6 | dotenv.config(); 7 | 8 | const startDev = async () => { 9 | await start(); 10 | await import(resolve(process.cwd(), "node", "server.js")); 11 | }; 12 | 13 | startDev(); 14 | -------------------------------------------------------------------------------- /ui/csr-example/build/scripts/startDevServer.ts: -------------------------------------------------------------------------------- 1 | import { WebpackDevServer } from "@site/webpack"; 2 | 3 | import { logger } from "./log"; 4 | 5 | import type { Compiler, Configuration } from "webpack"; 6 | 7 | export const startDevServer = (clientCompiler: Compiler, clientConfig: Configuration) => { 8 | const devServer = new WebpackDevServer(clientConfig.devServer, clientCompiler); 9 | 10 | devServer.startCallback(() => logger().info("🚀 Starting the development node server, please wait....")); 11 | 12 | return devServer; 13 | }; 14 | -------------------------------------------------------------------------------- /ui/csr-example/build/scripts/startServerWatch.ts: -------------------------------------------------------------------------------- 1 | import { logger } from "./log"; 2 | 3 | import type { Compiler } from "webpack"; 4 | 5 | export const startServerWatch = (serverCompiler: Compiler) => { 6 | serverCompiler.watch( 7 | { 8 | aggregateTimeout: 1000, 9 | ignored: ["**/node_modules/**", "**/dist/**", "**/dev/**"], 10 | }, 11 | (err, stats) => { 12 | if (err) { 13 | logger().error(err.stack || err.message); 14 | } 15 | 16 | if (stats?.hasErrors()) { 17 | logger().error(stats.toJson().errors); 18 | } 19 | 20 | if (stats?.hasWarnings()) { 21 | logger().warn(stats.toJson().warnings); 22 | } 23 | } 24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /ui/csr-example/build/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "esModuleInterop": true 5 | }, 6 | "include": ["../global.d.ts"], 7 | "ts-node": { 8 | "swc": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ui/csr-example/node/lib/copyFile.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | 4 | /** 5 | * 复制文件 6 | * @param {String} fileName 需要复制的文件名 7 | * @param {String} srcResolveDir 被复制文件所在文件夹的绝对路径 8 | * @param {String} targetResolveDir 目标文件夹的绝对路径 9 | */ 10 | function copyFileByPath(fileName, srcResolveDir, targetResolveDir) { 11 | let srcResolvePath = path.resolve(srcResolveDir, fileName); 12 | let targetResolvePath = path.resolve(targetResolveDir, fileName); 13 | return fs.promises.copyFile(srcResolvePath, targetResolvePath, fs.constants.COPYFILE_EXCL); 14 | } 15 | 16 | exports.copyFileByPath = copyFileByPath; 17 | -------------------------------------------------------------------------------- /ui/csr-example/node/lib/createFile.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs").promises; 2 | const { getFileExist } = require("./tools"); 3 | 4 | /** 5 | * 根据路径创建文件 6 | * @param {String} resolvePath 通过绝对路径创建文件 7 | */ 8 | function createFileByPath(resolvePath) { 9 | return getFileExist(resolvePath).then(() => fs.appendFile(resolvePath, "")); 10 | } 11 | 12 | exports.createFileByPath = createFileByPath; 13 | -------------------------------------------------------------------------------- /ui/csr-example/node/lib/createFolder.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs").promises; 2 | const { getFileExist } = require("./tools"); 3 | 4 | /** 5 | * 根据路径创建文件夹 6 | * @param {String} resolvePath 通过绝对路径创建文件夹 7 | */ 8 | function createFolderByPath(resolvePath) { 9 | return getFileExist(resolvePath).then(() => fs.mkdir(resolvePath)); 10 | } 11 | 12 | exports.createFolderByPath = createFolderByPath; 13 | -------------------------------------------------------------------------------- /ui/csr-example/node/lib/deleteFile.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs").promises; 2 | 3 | /** 4 | * 删除指定路径文件 5 | * @param {String} resolvePath 被删除文件绝对路径 6 | */ 7 | function deleteFileByPath(resolvePath) { 8 | return fs.unlink(resolvePath); 9 | } 10 | 11 | exports.deleteFileByPath = deleteFileByPath; 12 | -------------------------------------------------------------------------------- /ui/csr-example/node/lib/deleteFolder.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs").promises; 2 | 3 | /** 4 | * 递归删除指定文件夹 5 | * @param {String} resolvePath 被删除文件夹的绝对路径 6 | */ 7 | function deleteFolderByPath(resolvePath) { 8 | return fs.rmdir(resolvePath, { recursive: true }); 9 | } 10 | 11 | exports.deleteFolderByPath = deleteFolderByPath; 12 | -------------------------------------------------------------------------------- /ui/csr-example/node/lib/deleteItem.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const deleteFileByPath = require("./deleteFile").deleteFileByPath; 3 | const deleteFolderByPath = require("./deleteFolder").deleteFolderByPath; 4 | 5 | /** 6 | * 删除元素 7 | * @param {String} baseDir 绝对路径前缀 8 | * @param {Object} item -> type: file/dir, path: 相对路径 9 | */ 10 | function deleteItem(baseDir, item) { 11 | if (item.type === "file") { 12 | return deleteFileByPath(path.resolve(baseDir, item.path)); 13 | } else { 14 | return deleteFolderByPath(path.resolve(baseDir, item.path)); 15 | } 16 | } 17 | 18 | exports.deleteItem = deleteItem; 19 | -------------------------------------------------------------------------------- /ui/csr-example/node/lib/moveItem.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const mv = require("./mv").mv; 3 | 4 | // 将指定文件/文件夹移动 5 | function moveItem(originName, srcResolveDir, targetResolveDir) { 6 | let srcResolvePath = path.resolve(srcResolveDir, originName); 7 | let targetResolvePath = path.resolve(targetResolveDir, originName); 8 | return mv(srcResolvePath, targetResolvePath); 9 | } 10 | 11 | exports.moveItem = moveItem; 12 | -------------------------------------------------------------------------------- /ui/csr-example/node/lib/mv.js: -------------------------------------------------------------------------------- 1 | const exec = require("child_process").exec; 2 | 3 | // 将当前文件移动到指定文件中 4 | function mv(srcResolvePath, targetResolvePath) { 5 | return new Promise((resolve, reject) => { 6 | exec(`mv ${srcResolvePath} ${targetResolvePath}`, (error, data) => { 7 | resolve(data); 8 | reject(error); 9 | }); 10 | }); 11 | } 12 | 13 | exports.mv = mv; 14 | -------------------------------------------------------------------------------- /ui/csr-example/node/lib/readAbleStream.js: -------------------------------------------------------------------------------- 1 | const { Readable } = require("stream"); 2 | 3 | class MyReadable extends Readable { 4 | constructor(options) { 5 | // 调用 stream.Readable(options) 构造函数。 6 | super(options); 7 | } 8 | } 9 | 10 | exports.MyReadable = MyReadable; 11 | -------------------------------------------------------------------------------- /ui/csr-example/node/lib/renameItem.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs").promises; 2 | const path = require("path"); 3 | const { getFileExist } = require("./tools"); 4 | 5 | /** 6 | * 重命名文件 7 | * @param {String} resolveDir 需要重命名文件所在文件夹的绝对路径 8 | * @param {String} originName 文件原始名称 9 | * @param {String} newName 文件重命名后的名称 10 | */ 11 | function renameItemByPath(resolveDir, originName, newName) { 12 | newName = newName.split(/\s+/).join(""); 13 | let srcResolvePath = path.resolve(resolveDir, originName); 14 | let targetResolvePath = path.resolve(resolveDir, newName); 15 | return getFileExist(targetResolvePath).then(() => fs.rename(srcResolvePath, targetResolvePath)); 16 | } 17 | 18 | exports.renameItemByPath = renameItemByPath; 19 | -------------------------------------------------------------------------------- /ui/csr-example/node/user: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/csr-example/node/user -------------------------------------------------------------------------------- /ui/csr-example/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/csr-example/public/favicon.ico -------------------------------------------------------------------------------- /ui/csr-example/readme.md: -------------------------------------------------------------------------------- 1 | ## username: mrwang 2 | 3 | ## password: 123456 4 | 5 | ## NOTE: old version of `react-redux` not support react-18 lifecycle change, so `@my-react` build with new lifecycle also have bug (SEE `/myreact/share/env.ts`) 6 | 7 | ## todo 支持大文件上传以及断点续传 刚好有这个项目作为实验对象 8 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/dir/echartsContainer/echartsContainer.js: -------------------------------------------------------------------------------- 1 | import EchartsContainerHead from "./echartsContainerHead"; 2 | import EchartsContainerBody from "./echartsContainerBody"; 3 | import { useSelector } from "react-redux"; 4 | 5 | function EchartsContainer() { 6 | let { isLoaded } = useSelector((state) => state); 7 | return ( 8 |
9 | 10 | {isLoaded && } 11 |
12 | ); 13 | } 14 | 15 | export default EchartsContainer; 16 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/dir/fileContainer/block/fileBlock.js: -------------------------------------------------------------------------------- 1 | import { memo } from "react"; 2 | import { useSelector } from "react-redux"; 3 | import FileBlockBody from "./fileBlockBody"; 4 | 5 | function FileBlock() { 6 | let { isLoaded } = useSelector((state) => state); 7 | return
{isLoaded && }
; 8 | } 9 | 10 | export default FileBlock; 11 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/dir/fileContainer/block/fileBlockBody.js: -------------------------------------------------------------------------------- 1 | import { useSelector } from "react-redux"; 2 | import FileBlockFileItem from "./fileBlockFileItem"; 3 | import FileBlockDirItem from "./fileBlockDirItem"; 4 | import * as Allfilter from "../../../tools/listFilter"; 5 | 6 | function FileBlockBody() { 7 | let { filterName, data } = useSelector((state) => state); 8 | return ( 9 | <> 10 | {data.files.map((it) => { 11 | return it.fileType === "file" ? ( 12 | Allfilter[filterName](it.shortPath) && 13 | ) : ( 14 | 15 | ); 16 | })} 17 | 18 | ); 19 | } 20 | 21 | export default FileBlockBody; 22 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/dir/fileContainer/block/fileBlockDirItem.js: -------------------------------------------------------------------------------- 1 | import { Link } from "react-router-dom"; 2 | 3 | function FileBlockDirItem(props) { 4 | return ( 5 |
6 | 7 | 8 | {props.shortPath} 9 | 10 |
11 | ); 12 | } 13 | 14 | export default FileBlockDirItem; 15 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/dir/fileContainer/fileContainerHead.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import FileContainerHeadLeftBtn from "./fileContainerHeadLeftBtn"; 3 | import FileContainerHeadRightBtn from "./fileContainerHeadRightBtn"; 4 | 5 | function FileContainerHead() { 6 | return ( 7 |
8 | 9 | 10 |
11 | ); 12 | } 13 | 14 | export default React.memo(FileContainerHead); 15 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/dir/fileContainer/fileContainerHeadLeftBtn.js: -------------------------------------------------------------------------------- 1 | import FileContainerHeadUploadFile from "./fileContainerHeadUploadFile"; 2 | import FileContainerHeadAddFile from "./fileContainerHeadAddFile"; 3 | import FileContainerHeadAddDir from "./fileContainerHeadAddDir"; 4 | import FileContainerHeadDownloadFile from "./fileContainerHeadDownloadFile"; 5 | 6 | function FileContainerHeadLeftBtn() { 7 | return ( 8 |
9 | 10 | 11 | 12 | 13 |
14 | ); 15 | } 16 | 17 | export default FileContainerHeadLeftBtn; 18 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/dir/fileContainer/table/fileTableFileItemCheck.js: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | 4 | // 文件选中 5 | function FileTbaleFileCheck(props) { 6 | let dispatch = useDispatch(); 7 | 8 | let checkHandler = useCallback(() => { 9 | dispatch({ type: "changeFileItemCheck", id: props.id }); 10 | }, [props, dispatch]); 11 | 12 | return ( 13 |
14 | 15 |
16 | ); 17 | } 18 | 19 | export default FileTbaleFileCheck; 20 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/dir/menu/fileMenuEditorItem.js: -------------------------------------------------------------------------------- 1 | import { useDispatch, useSelector } from "react-redux"; 2 | import { useHistory } from "react-router"; 3 | 4 | // 编辑文件 5 | function FileMenuEditorItem() { 6 | let history = useHistory(); 7 | let dispatch = useDispatch(); 8 | let { menuTarget } = useSelector((state) => state); 9 | return ( 10 |
  • { 13 | history.push(menuTarget); 14 | dispatch({ type: "menuHide" }); 15 | }} 16 | > 17 | 18 | 编辑 19 |
  • 20 | ); 21 | } 22 | 23 | export default FileMenuEditorItem; 24 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/dir/menu/fileMenuRenameItem.js: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | 4 | function FileMenuRenameItem() { 5 | let dispatch = useDispatch(); 6 | // 重命名按钮点击 7 | let renameHandler = useCallback(() => { 8 | dispatch({ type: "renameItem" }); 9 | }, [dispatch]); 10 | return ( 11 |
  • 12 | 13 | 重命名 14 |
  • 15 | ); 16 | } 17 | 18 | export default FileMenuRenameItem; 19 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/file.js: -------------------------------------------------------------------------------- 1 | import { useSelector } from "react-redux"; 2 | import { useHistory } from "react-router"; 3 | import FileContainer from "./file/fileContainer"; 4 | 5 | // 显示文件的父组件 6 | function File() { 7 | // 判断当前资源是否加载 8 | let history = useHistory(); 9 | let { isLogin } = useSelector((state) => state); 10 | 11 | if (!isLogin) { 12 | history.push("/login"); 13 | } 14 | 15 | return ; 16 | } 17 | 18 | export default File; 19 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/file/codemirror/codemirrorOption.js: -------------------------------------------------------------------------------- 1 | export const option = { 2 | lineNumbers: true, 3 | theme: "idea", 4 | tabSize: 2, 5 | gutters: ["CodeMirror-linenumbers"], 6 | matchBrackets: true, 7 | }; 8 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/file/codemirror/editorLoad.js: -------------------------------------------------------------------------------- 1 | import "./load.css"; 2 | 3 | function Load(props) { 4 | return ( 5 |
    6 |
    7 |
    8 | ); 9 | } 10 | 11 | export default Load; 12 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/file/previewAudio/audio.js: -------------------------------------------------------------------------------- 1 | import { useParams } from "react-router"; 2 | import BackButton from "./audioCloseButton"; 3 | 4 | function Audio() { 5 | let { 0: src } = useParams(); 6 | 7 | return ( 8 |
    9 |
    10 | 11 |
    13 |
    14 | ); 15 | } 16 | 17 | export default Audio; 18 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/file/previewVideo/video.js: -------------------------------------------------------------------------------- 1 | import { useParams } from "react-router"; 2 | import BackButton from "./videoCloseButton"; 3 | 4 | function Video() { 5 | let { 0: src } = useParams(); 6 | 7 | return ( 8 |
    9 |
    10 | 11 |
    13 |
    14 | ); 15 | } 16 | 17 | export default Video; 18 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/head/head.js: -------------------------------------------------------------------------------- 1 | // head组件 2 | import HeadLogo from "./headLogo"; 3 | import HeadPath from "./headPath"; 4 | import HeadUser from "./headUser"; 5 | import "./head.css"; 6 | 7 | function Head() { 8 | return ( 9 |
    10 |
    11 | 12 | 13 | 14 |
    15 |
    16 | ); 17 | } 18 | 19 | export default Head; 20 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/head/headLogo.js: -------------------------------------------------------------------------------- 1 | import { Link } from "react-router-dom"; 2 | 3 | function Logo(props) { 4 | return ( 5 |
    6 |

    7 | 8 | {props.title} 9 | 10 |

    11 |
    12 | ); 13 | } 14 | 15 | export default Logo; 16 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/head/headPath.js: -------------------------------------------------------------------------------- 1 | import { Link } from "react-router-dom"; 2 | import { useSelector } from "react-redux"; 3 | 4 | function IndexPath() { 5 | let { currentRequestPathArr } = useSelector((state) => state); 6 | let pre = ""; 7 | return ( 8 |
    9 |
      10 | {currentRequestPathArr.map((it, index) => { 11 | pre += it; 12 | return ( 13 |
    • 14 | {it} 15 |
    • 16 | ); 17 | })} 18 |
    19 |
    20 | ); 21 | } 22 | 23 | export default IndexPath; 24 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/head/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/csr-example/src/client/component/head/logo.jpg -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/msg.js: -------------------------------------------------------------------------------- 1 | import MsgContainer from "./msg/msgContainer"; 2 | 3 | // 显示提示信息 4 | function Msg() { 5 | return ; 6 | } 7 | 8 | export default Msg; 9 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/msg/msgContainerBtn.js: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | 4 | function MsgContainerBtn() { 5 | let dispatch = useDispatch(); 6 | let closeMsgHandler = useCallback(() => { 7 | dispatch({ type: "msgStatePadding" }); 8 | }, [dispatch]); 9 | 10 | return ( 11 | 14 | ); 15 | } 16 | 17 | export default MsgContainerBtn; 18 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/nav/nav.js: -------------------------------------------------------------------------------- 1 | import NavFile from "./navFile"; 2 | import NavEcharts from "./navEcharts"; 3 | import NavRecover from "./navRecover"; 4 | import NavTotalSize from "./navTotalSize"; 5 | import "./nav.css"; 6 | 7 | function Nav() { 8 | return ( 9 | 17 | ); 18 | } 19 | 20 | export default Nav; 21 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/recover/fileContainer/fileRecover.js: -------------------------------------------------------------------------------- 1 | import { useSelector } from "react-redux"; 2 | import FileRecoverBody from "./fileRecoverBody"; 3 | 4 | function FileRecover() { 5 | let { isLoaded } = useSelector((state) => state); 6 | return ( 7 |
    8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | {isLoaded && } 17 |
    文件名大小修改日期
    18 |
    19 | ); 20 | } 21 | 22 | export default FileRecover; 23 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/recover/fileContainer/fileRecoverBody.js: -------------------------------------------------------------------------------- 1 | import { useSelector } from "react-redux"; 2 | import FileRecoverFileItem from "./fileRecoverFileItem"; 3 | import FileRecoverDirItem from "./fileRecoverDirItem"; 4 | 5 | function FileRecoverBody() { 6 | let { data } = useSelector((state) => state); 7 | return ( 8 | 9 | {data.files.map((it) => { 10 | return it.fileType === "file" ? : ; 11 | })} 12 | 13 | ); 14 | } 15 | 16 | export default FileRecoverBody; 17 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/recover/fileContainer/fileRecoverDirItem.js: -------------------------------------------------------------------------------- 1 | import FileRecoverItemCheck from "./fileRecoverItemCheck"; 2 | 3 | function FileTableDirItem(props) { 4 | return ( 5 | 6 | 7 | 8 | 9 | {props.shortPath} 10 | 11 | 12 | {props.readAbleLength} 13 | 14 | 15 | {props.modifyTime} 16 | 17 | 18 | ); 19 | } 20 | 21 | export default FileTableDirItem; 22 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/recover/fileContainer/fileRecoverFileItem.js: -------------------------------------------------------------------------------- 1 | import FileRecoverItemCheck from "./fileRecoverItemCheck"; 2 | 3 | function FileTableFileItem(props) { 4 | return ( 5 | 6 | 7 | 8 | 9 | {props.shortPath} 10 | 11 | 12 | {props.readAbleLength} 13 | 14 | 15 | {props.modifyTime} 16 | 17 | 18 | ); 19 | } 20 | 21 | export default FileTableFileItem; 22 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/recover/fileContainer/fileRecoverItemCheck.js: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | 4 | // 文件选中 5 | function FileTbaleFileCheck(props) { 6 | let dispatch = useDispatch(); 7 | 8 | let checkHandler = useCallback(() => { 9 | dispatch({ type: "changeFileItemCheck", id: props.id }); 10 | }, [props, dispatch]); 11 | 12 | return ( 13 |
    14 | 15 |
    16 | ); 17 | } 18 | 19 | export default FileTbaleFileCheck; 20 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/recover/recoverContainerHead.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import FileContainerHeadLeftBtn from "./recoverContainerHeadLeftBtn"; 3 | import FileContainerHeadRightBtn from "./recoverContainerHeadRightBtn"; 4 | 5 | function FileContainerHead() { 6 | return ( 7 |
    8 | 9 | 10 |
    11 | ); 12 | } 13 | 14 | export default React.memo(FileContainerHead); 15 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/recover/recoverContainerHeadLeftBtn.js: -------------------------------------------------------------------------------- 1 | import RecoverContainerHeadDeleteFile from "./recoverContainerHeadDeleteFile"; 2 | import RecoverContainerHeadCheckAll from "./recoverContainerHeadCheckAll"; 3 | 4 | function FileContainerHeadLeftBtn() { 5 | return ( 6 |
    7 | 8 | 9 | 15 |
    16 | ); 17 | } 18 | 19 | export default FileContainerHeadLeftBtn; 20 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/recover/recoverContainerHeadRightBtn.js: -------------------------------------------------------------------------------- 1 | function FileContainerHeadRightBtn() { 2 | return ( 3 |
    4 | 8 |
    9 | ); 10 | } 11 | 12 | export default FileContainerHeadRightBtn; 13 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/tools/listFilter.js: -------------------------------------------------------------------------------- 1 | import mime from "mime"; 2 | function filterDefault(path) { 3 | return true; 4 | } 5 | // 文件过滤 6 | function filterText(item) { 7 | try { 8 | return mime.getType(item).startsWith("text"); 9 | } catch (e) { 10 | return true; 11 | } 12 | } 13 | // 图片过滤 14 | function filterImg(item) { 15 | try { 16 | return mime.getType(item).startsWith("image"); 17 | } catch (e) { 18 | return true; 19 | } 20 | } 21 | // 视频过滤 22 | function filterVideo(item) { 23 | try { 24 | return mime.getType(item).startsWith("video"); 25 | } catch (e) { 26 | return true; 27 | } 28 | } 29 | 30 | export { filterDefault, filterText, filterImg, filterVideo }; 31 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/tools/tools.js: -------------------------------------------------------------------------------- 1 | const getColor = () => "#" + Math.random().toString(16).slice(2, 5); 2 | 3 | const getRandom = (start, end) => ((Math.random() * (end - start)) | 0) + start; 4 | 5 | const promiseNext = (time, action) => 6 | new Promise((resolve) => { 7 | setTimeout(() => { 8 | if (action) { 9 | action(); 10 | } 11 | resolve(); 12 | }, time); 13 | }); 14 | 15 | export { getColor, getRandom, promiseNext }; 16 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/welcome.js: -------------------------------------------------------------------------------- 1 | import WelcomeContainer from "./welcome/welcomeContainer"; 2 | 3 | // 登录/注册页面 4 | function Welcome() { 5 | return ; 6 | } 7 | 8 | export default Welcome; 9 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/welcome/loginContainerSubmit.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | // 提交登录请求 4 | 5 | export default React.forwardRef((props, ref) => { 6 | function Submit(props) { 7 | return ( 8 |
    9 | 12 |
    13 | ); 14 | } 15 | return ; 16 | }); 17 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/welcome/loginContainerUsername.js: -------------------------------------------------------------------------------- 1 | function LoginContainerUsername() { 2 | return ( 3 | 7 | ); 8 | } 9 | 10 | export default LoginContainerUsername; 11 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/welcome/registerContainerInviteCode.js: -------------------------------------------------------------------------------- 1 | function RegisterContainerInviteCode() { 2 | return ( 3 | 7 | ); 8 | } 9 | 10 | export default RegisterContainerInviteCode; 11 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/welcome/registerContainerPassword.js: -------------------------------------------------------------------------------- 1 | import { useCallback, useState } from "react"; 2 | 3 | function LoginContainerPassword() { 4 | const [passwordCheck, setPasswordCheck] = useState(true); 5 | 6 | let passwordHandler = useCallback(() => { 7 | setPasswordCheck(!passwordCheck); 8 | }, [passwordCheck]); 9 | 10 | return ( 11 | 15 | ); 16 | } 17 | 18 | export default LoginContainerPassword; 19 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/welcome/registerContainerSubmit.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | // 提交注册请求 4 | 5 | export default React.forwardRef((props, ref) => { 6 | function Submit(props) { 7 | return ( 8 |
    9 | 12 |
    13 | ); 14 | } 15 | return ; 16 | }); 17 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/welcome/welcomeContainerFoot.js: -------------------------------------------------------------------------------- 1 | function WelcomeContainerFoot() { 2 | return ( 3 |
    4 |

    5 | Copyright 2019-2020 MrWang 6 |

    7 |
    8 | ); 9 | } 10 | 11 | export default WelcomeContainerFoot; 12 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/component/welcome/welcomeContainerHead.js: -------------------------------------------------------------------------------- 1 | function WelcomeContainerHead(props) { 2 | return

    {props.title} - power by @my-react

    ; 3 | } 4 | 5 | export default WelcomeContainerHead; 6 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/css/loginBackground.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/csr-example/src/client/css/loginBackground.jpg -------------------------------------------------------------------------------- /ui/csr-example/src/client/entry.js: -------------------------------------------------------------------------------- 1 | import { render } from "react-dom"; 2 | // import { render } from "./test"; 3 | import { __my_react_dom_shared__ } from "@my-react/react-dom"; 4 | import "./index.css"; 5 | import App from "./App"; 6 | 7 | __my_react_dom_shared__.enableDebugUpdateQueue.current = true; 8 | 9 | render(, document.getElementById("__content__")); 10 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; 4 | -webkit-font-smoothing: antialiased; 5 | -moz-osx-font-smoothing: grayscale; 6 | } 7 | 8 | code { 9 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace; 10 | } 11 | 12 | #__content__ { 13 | height: 100%; 14 | width: 100%; 15 | overflow: hidden; 16 | } 17 | -------------------------------------------------------------------------------- /ui/csr-example/src/client/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/csr-example/src/client/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /ui/csr-example/src/client/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/csr-example/src/client/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /ui/csr-example/src/client/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/csr-example/src/client/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /ui/csr-example/src/client/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/csr-example/src/client/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /ui/csr-example/src/client/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/csr-example/src/client/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /ui/csr-example/src/client/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/csr-example/src/client/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /ui/csr-example/src/client/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/csr-example/src/client/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /ui/csr-example/src/client/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/csr-example/src/client/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /ui/csr-example/src/client/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/csr-example/src/client/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /ui/csr-example/src/client/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/csr-example/src/client/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /ui/csr-example/src/client/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/csr-example/src/client/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /ui/csr-example/src/client/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/csr-example/src/client/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /ui/csr-example/src/server/entry.ts: -------------------------------------------------------------------------------- 1 | import { generateRender } from "./render"; 2 | 3 | import type { Express } from "express"; 4 | 5 | let handlerRender = generateRender; 6 | 7 | const startApp = (app: Express) => { 8 | app.use(async (req, res) => { 9 | const render = handlerRender(); 10 | await render(req, res); 11 | }); 12 | 13 | if (__DEVELOPMENT__ && module.hot) { 14 | module.hot.accept("./render.tsx", () => { 15 | handlerRender = generateRender; 16 | }); 17 | module.hot.dispose(() => process.exit(0)); 18 | } 19 | }; 20 | 21 | export { startApp }; 22 | -------------------------------------------------------------------------------- /ui/csr-example/src/server/template/Body.tsx: -------------------------------------------------------------------------------- 1 | import type { HTMLProps } from "."; 2 | 3 | export const Body = ({ children, script = [], refresh = [] }: HTMLProps) => ( 4 | 5 |
    6 | {script.filter(Boolean).map((ele) => ele)} 7 | {refresh.filter(Boolean).map((ele) => ele)} 8 | 9 | ); 10 | -------------------------------------------------------------------------------- /ui/csr-example/src/server/template/index.tsx: -------------------------------------------------------------------------------- 1 | import { Body } from "./Body"; 2 | import { Head } from "./Head"; 3 | 4 | import type { ReactElement } from "react"; 5 | 6 | export type HTMLProps = { 7 | env?: string; 8 | lang?: string; 9 | children?: string; 10 | preloadedState?: string; 11 | link?: ReactElement[]; 12 | script?: ReactElement[]; 13 | refresh?: ReactElement[]; 14 | preLoad?: ReactElement[]; 15 | }; 16 | 17 | export const HTML = (props: HTMLProps) => { 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | }; 25 | -------------------------------------------------------------------------------- /ui/csr-example/src/server/util.ts: -------------------------------------------------------------------------------- 1 | import path from "path"; 2 | 3 | const outputPath = (env: "server" | "client"): string => (__DEVELOPMENT__ ? path.resolve(process.cwd(), "dev", env) : path.resolve(process.cwd(), "dist", env)); 4 | 5 | const manifestFile = (): string => (__DEVELOPMENT__ ? "manifest-dev.json" : "manifest-prod.json"); 6 | 7 | const manifestStateFile = (env: "server" | "client"): string => path.resolve(outputPath(env), manifestFile()); 8 | 9 | const manifestLoadableFile = (env: "server" | "client"): string => path.resolve(outputPath(env), "manifest-loadable.json"); 10 | 11 | export { manifestStateFile, manifestLoadableFile }; 12 | -------------------------------------------------------------------------------- /ui/csr-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2018", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": false, 8 | "forceConsistentCasingInFileNames": true, 9 | "experimentalDecorators": true, 10 | "noEmit": true, 11 | "esModuleInterop": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "jsx": "react-jsx", 17 | "incremental": true, 18 | "baseUrl": ".", 19 | "types": ["node", "webpack-env"] 20 | }, 21 | "exclude": ["dist", "dev", "node_modules"], 22 | "include": ["**/*.ts", "**/*.tsx"] 23 | } 24 | -------------------------------------------------------------------------------- /ui/next-example/.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 | 30 | # vercel 31 | .vercel 32 | 33 | # typescript 34 | *.tsbuildinfo 35 | next-env.d.ts 36 | -------------------------------------------------------------------------------- /ui/next-example/README.md: -------------------------------------------------------------------------------- 1 | ## use @my-react in next 2 | -------------------------------------------------------------------------------- /ui/next-example/components/Bar.tsx: -------------------------------------------------------------------------------- 1 | export const Bar = () => { 2 | return ( 3 |
    4 | lazy load component: {"<"}Bar{" />"} 5 |
    6 | ); 7 | }; 8 | -------------------------------------------------------------------------------- /ui/next-example/index.js: -------------------------------------------------------------------------------- 1 | require("module-alias/register"); 2 | 3 | require("./server"); 4 | -------------------------------------------------------------------------------- /ui/next-example/next.config.mjs: -------------------------------------------------------------------------------- 1 | import withNext from "@my-react/react-refresh-tools/withNext"; 2 | 3 | /** @type {import('next').NextConfig} */ 4 | const config = { 5 | reactStrictMode: true, 6 | experimental: { 7 | reactCompiler: { 8 | target: "18", 9 | }, // or React Compiler options 10 | }, 11 | }; 12 | 13 | const nextConfig = withNext(config); 14 | 15 | // export default config; 16 | 17 | export default nextConfig; 18 | -------------------------------------------------------------------------------- /ui/next-example/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import type { AppProps } from "next/app"; 2 | import "../styles/globals.css"; 3 | 4 | export default function App({ Component, pageProps }: AppProps) { 5 | return ; 6 | } 7 | -------------------------------------------------------------------------------- /ui/next-example/pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import { Html, Head, Main, NextScript } from "next/document"; 2 | 3 | export default function Document() { 4 | return ( 5 | 6 | 7 | 8 |
    9 | 10 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /ui/next-example/pages/api/hello.ts: -------------------------------------------------------------------------------- 1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction 2 | import type { NextApiRequest, NextApiResponse } from "next"; 3 | 4 | type Data = { 5 | name: string; 6 | }; 7 | 8 | export default function handler(req: NextApiRequest, res: NextApiResponse) { 9 | res.status(200).json({ name: "John Doe" }); 10 | } 11 | -------------------------------------------------------------------------------- /ui/next-example/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /ui/next-example/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/next-example/public/favicon.ico -------------------------------------------------------------------------------- /ui/next-example/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/next-example/server.js: -------------------------------------------------------------------------------- 1 | const { createServer } = require("http"); 2 | const { parse } = require("url"); 3 | const next = require("next"); 4 | 5 | const port = parseInt(process.env.PORT || "3000", 10); 6 | const dev = process.env.NODE_ENV !== "production"; 7 | const app = next({ dev, hostname: "localhost", port }); 8 | const handle = app.getRequestHandler(); 9 | 10 | app 11 | .prepare() 12 | .then(() => { 13 | createServer((req, res) => { 14 | const parsedUrl = parse(req.url, true); 15 | handle(req, res, parsedUrl); 16 | }).listen(port); 17 | 18 | console.log(`> Server listening at http://localhost:${port} as ${dev ? "development" : process.env.NODE_ENV}`); 19 | }) 20 | .catch(console.log); 21 | -------------------------------------------------------------------------------- /ui/next-example/styles/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | --foreground-rgb: 0, 0, 0; 7 | --background-start-rgb: 214, 219, 220; 8 | --background-end-rgb: 255, 255, 255; 9 | } 10 | 11 | @media (prefers-color-scheme: dark) { 12 | :root { 13 | --foreground-rgb: 255, 255, 255; 14 | --background-start-rgb: 0, 0, 0; 15 | --background-end-rgb: 0, 0, 0; 16 | } 17 | } 18 | 19 | body { 20 | color: rgb(var(--foreground-rgb)); 21 | background: linear-gradient(to bottom, transparent, rgb(var(--background-end-rgb))) rgb(var(--background-start-rgb)); 22 | } 23 | -------------------------------------------------------------------------------- /ui/next-example/tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "tailwindcss"; 2 | 3 | const config: Config = { 4 | content: ["./pages/**/*.{js,ts,jsx,tsx,mdx}", "./components/**/*.{js,ts,jsx,tsx,mdx}", "./app/**/*.{js,ts,jsx,tsx,mdx}"], 5 | theme: { 6 | extend: { 7 | backgroundImage: { 8 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))", 9 | "gradient-conic": "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))", 10 | }, 11 | }, 12 | }, 13 | plugins: [], 14 | }; 15 | 16 | export default config; 17 | -------------------------------------------------------------------------------- /ui/next-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "baseUrl": ".", 17 | "incremental": true, 18 | "plugins": [ 19 | { 20 | "name": "next" 21 | } 22 | ] 23 | }, 24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 25 | "exclude": ["node_modules"] 26 | } 27 | -------------------------------------------------------------------------------- /ui/remix-example/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [require.resolve("project-tool/baseLint"), require.resolve("project-tool/reactLint")], 3 | env: { 4 | browser: true, 5 | es2021: true, 6 | }, 7 | ignorePatterns: [".eslintrc.cjs", "postcss.config.cjs", "vite.config.ts", "!**/.server", "!**/.client"], 8 | parserOptions: { 9 | ecmaFeatures: { 10 | jsx: true, 11 | }, 12 | sourceType: "module", 13 | tsconfigRootDir: __dirname, 14 | project: "./tsconfig.json", 15 | }, 16 | }; 17 | -------------------------------------------------------------------------------- /ui/remix-example/app/components/Test.tsx: -------------------------------------------------------------------------------- 1 | export const Test = () => { 2 | return
    Test
    ; 3 | } -------------------------------------------------------------------------------- /ui/remix-example/app/routes/Foo.tsx: -------------------------------------------------------------------------------- 1 | import { useLoaderData, type MetaFunction } from "@remix-run/react"; 2 | 3 | import type { LoaderFunction } from "@remix-run/node"; 4 | 5 | export const meta: MetaFunction = () => { 6 | return [ 7 | { 8 | title: "Foo Page 123", 9 | description: "This is the foo page", 10 | }, 11 | ]; 12 | }; 13 | 14 | export const loader: LoaderFunction = async () => { 15 | await new Promise((resolve) => { 16 | setTimeout(resolve, 1000); 17 | }); 18 | 19 | return { message: "Hello" }; 20 | }; 21 | 22 | export default function Index() { 23 | const data = useLoaderData(); 24 | 25 | console.warn("loader data:", data); 26 | 27 | return
    Foo page
    ; 28 | } 29 | -------------------------------------------------------------------------------- /ui/remix-example/app/styles/styles.css: -------------------------------------------------------------------------------- 1 | html { 2 | --background-colour: white; 3 | 4 | background-color: var(--background-colour); 5 | } 6 | 7 | html.dark { 8 | --background-colour: black; 9 | } 10 | 11 | .dark-component { 12 | color: white; 13 | } 14 | 15 | .light-component { 16 | color: black; 17 | } 18 | -------------------------------------------------------------------------------- /ui/remix-example/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/remix-example/public/favicon.ico -------------------------------------------------------------------------------- /ui/rspack-example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 |
    13 | 14 | 15 | -------------------------------------------------------------------------------- /ui/rspack-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rspack-example", 3 | "version": "1.0.0", 4 | "private": true, 5 | "license": "MIT", 6 | "main": "index.js", 7 | "scripts": { 8 | "build": "cross-env NODE_ENV=production rspack build", 9 | "dev": "rspack serve " 10 | }, 11 | "dependencies": { 12 | "@my-react/react": "workspace:*", 13 | "@my-react/react-dom": "workspace:*", 14 | "react": "^18.3.1", 15 | "react-dom": "^18.3.1" 16 | }, 17 | "devDependencies": { 18 | "@my-react/react-refresh": "workspace:*", 19 | "@my-react/react-rspack": "workspace:*", 20 | "@rspack/cli": "1.3.2", 21 | "@rspack/core": "1.3.2" 22 | } 23 | } -------------------------------------------------------------------------------- /ui/rspack-example/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { lazy, Suspense } from 'react'; 2 | 3 | import { ArrowFunction } from './ArrowFunction'; 4 | import ClassDefault from './ClassDefault'; 5 | import { ClassNamed } from './ClassNamed'; 6 | import FunctionDefault from './FunctionDefault'; 7 | import { FunctionNamed } from './FunctionNamed'; 8 | 9 | const LazyComponent = lazy(() => import('./LazyComponent')); 10 | 11 | function App() { 12 | return ( 13 |
    14 | 15 | 16 | 17 | 18 | 19 | Loading}> 20 | 21 | 22 |
    23 | ); 24 | } 25 | 26 | export default App; -------------------------------------------------------------------------------- /ui/rspack-example/src/ArrowFunction.tsx: -------------------------------------------------------------------------------- 1 | export const ArrowFunction = () =>

    Arrow Function

    ; -------------------------------------------------------------------------------- /ui/rspack-example/src/ClassDefault.tsx: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | 3 | class ClassDefault extends Component { 4 | render() { 5 | return

    Default Export Class

    ; 6 | } 7 | } 8 | 9 | export default ClassDefault; -------------------------------------------------------------------------------- /ui/rspack-example/src/ClassNamed.tsx: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | 3 | export class ClassNamed extends Component { 4 | render() { 5 | return

    Named Export Class

    ; 6 | } 7 | } -------------------------------------------------------------------------------- /ui/rspack-example/src/FunctionDefault.tsx: -------------------------------------------------------------------------------- 1 | function FunctionDefault() { 2 | return

    Default Export Function

    ; 3 | } 4 | 5 | export default FunctionDefault; -------------------------------------------------------------------------------- /ui/rspack-example/src/FunctionNamed.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | 3 | export function FunctionNamed() { 4 | const [data, setData] = useState(0); 5 | 6 | useEffect(() => { 7 | setInterval(() => { 8 | setData((i) => i + 1); 9 | }, 100); 10 | }, []); 11 | 12 | return

    Named Export Function {data}

    ; 13 | } -------------------------------------------------------------------------------- /ui/rspack-example/src/LazyComponent.tsx: -------------------------------------------------------------------------------- 1 | function LazyComponent() { 2 | return

    Lazy Component

    ; 3 | } 4 | 5 | export default LazyComponent; -------------------------------------------------------------------------------- /ui/rspack-example/src/index.tsx: -------------------------------------------------------------------------------- 1 | import { createRoot } from "react-dom/client"; 2 | 3 | import App from "./App"; 4 | 5 | const container = document.getElementById("root"); 6 | const root = createRoot(container!); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /ui/rspack-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "preserve" 4 | } 5 | } -------------------------------------------------------------------------------- /ui/ssr-example/.browserslistrc: -------------------------------------------------------------------------------- 1 | last 1 version 2 | ie >= 11 3 | > 1% 4 | -------------------------------------------------------------------------------- /ui/ssr-example/.env: -------------------------------------------------------------------------------- 1 | # dev env 2 | DEV_HOST=localhost 3 | DEV_PORT=9000 4 | WDS_PORT=9001 5 | PUBLIC_DEV_API_HOST=http://localhost:9000 6 | # prod env 7 | PROD_PORT=8000 8 | PROD_HOST=localhost 9 | PUBLIC_PROD_API_HOST=http://localhost:8000 10 | # switch render framework --> myreact | react, also need switch from @my-react to react package in the progect code 11 | REACT=myreact 12 | 13 | STREAM=true 14 | # feature 15 | SSR=true 16 | CSR=false 17 | MIDDLEWARE=false 18 | ANIMATE_ROUTER=false 19 | # entry 20 | SERVER_ENTRY=./src/server/entry.ts 21 | CLIENT_ENTRY=./src/client/entry.tsx 22 | 23 | BASENAME=MyReact 24 | -------------------------------------------------------------------------------- /ui/ssr-example/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [require.resolve("project-tool/baseLint"), require.resolve("project-tool/reactLint")], 3 | env: { 4 | browser: true, 5 | es2021: true, 6 | }, 7 | plugins: ["eslint-plugin-react-compiler"], 8 | rules: { 9 | "react-compiler/react-compiler": "error", 10 | "react/no-unknown-property": "off" 11 | }, 12 | parserOptions: { 13 | ecmaFeatures: { 14 | jsx: true, 15 | }, 16 | sourceType: "module", 17 | tsconfigRootDir: __dirname, 18 | project: "./tsconfig.json", 19 | }, 20 | }; 21 | -------------------------------------------------------------------------------- /ui/ssr-example/build/scripts/build-prod.ts: -------------------------------------------------------------------------------- 1 | import dotenv from "dotenv"; 2 | 3 | import { start } from "./entry-prod"; 4 | 5 | dotenv.config(); 6 | 7 | start(); 8 | -------------------------------------------------------------------------------- /ui/ssr-example/build/scripts/build-static.ts: -------------------------------------------------------------------------------- 1 | import { spawn } from "child_process"; 2 | import dotenv from "dotenv"; 3 | 4 | import { start } from "./entry-prod"; 5 | 6 | dotenv.config(); 7 | 8 | const generate = async () => { 9 | await start(); 10 | spawn("cross-env STATIC_GENERATE=true node", ["./build/scripts/start-app.js"], { shell: true, stdio: "inherit" }); 11 | }; 12 | 13 | generate(); 14 | -------------------------------------------------------------------------------- /ui/ssr-example/build/scripts/log.ts: -------------------------------------------------------------------------------- 1 | import { pino } from "pino"; 2 | import pretty from "pino-pretty"; 3 | 4 | export const logger = () => pino(pretty()); 5 | -------------------------------------------------------------------------------- /ui/ssr-example/build/scripts/start-app.js: -------------------------------------------------------------------------------- 1 | const dotenv = require("dotenv"); 2 | const path = require("path"); 3 | 4 | dotenv.config(); 5 | 6 | if (process.env.REACT === "myreact") { 7 | require("module-alias/register"); 8 | } 9 | 10 | if (process.env.NODE_ENV === "development") { 11 | require(path.resolve(process.cwd(), "dev", "server", "app.js")); 12 | } else { 13 | require(path.resolve(process.cwd(), "dist", "server", "app.js")); 14 | } 15 | -------------------------------------------------------------------------------- /ui/ssr-example/build/scripts/start-dev.ts: -------------------------------------------------------------------------------- 1 | import dotenv from "dotenv"; 2 | 3 | import { start } from "./entry-dev"; 4 | 5 | dotenv.config(); 6 | 7 | const startDev = async () => { 8 | await start(); 9 | await import("./start-app"); 10 | }; 11 | 12 | startDev(); 13 | -------------------------------------------------------------------------------- /ui/ssr-example/build/scripts/startDevServer.ts: -------------------------------------------------------------------------------- 1 | import { WebpackDevServer } from "@site/webpack"; 2 | 3 | import { logger } from "./log"; 4 | 5 | import type { Compiler, Configuration } from "webpack"; 6 | 7 | export const startDevServer = (clientCompiler: Compiler, clientConfig: Configuration) => { 8 | const devServer = new WebpackDevServer(clientConfig.devServer, clientCompiler); 9 | 10 | devServer.startCallback(() => logger().info("🚀 Starting the development node server, please wait....")); 11 | 12 | return devServer; 13 | }; 14 | -------------------------------------------------------------------------------- /ui/ssr-example/build/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "esModuleInterop": true 6 | }, 7 | "include": ["../global.d.ts"], 8 | "ts-node": { 9 | "swc": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ui/ssr-example/lang/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "blog": "@my-react Blog Example", 3 | "@my-react": "@my-react", 4 | "description": "A React like framework, can be used to replace all of the react/react-dom api for test、learn、debug ...", 5 | "hmr": "Hot module replacement", 6 | "config": "Internal config", 7 | "tldraw": "Tldraw ✍️", 8 | "excalidraw": "Excalidraw ✍️" 9 | } 10 | -------------------------------------------------------------------------------- /ui/ssr-example/lang/zh.json: -------------------------------------------------------------------------------- 1 | { 2 | "blog": "@my-react 博客", 3 | "@my-react": "@my-react", 4 | "description": "一个React like 项目,可以替换 react/react-dom 的所有api用于学习、测试、debug...", 5 | "hmr": "热模块重载", 6 | "config": "内部配置", 7 | "tldraw": "Tldraw ✍️", 8 | "excalidraw": "Excalidraw ✍️" 9 | } 10 | -------------------------------------------------------------------------------- /ui/ssr-example/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: ["autoprefixer"], 3 | }; 4 | -------------------------------------------------------------------------------- /ui/ssr-example/public/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/ssr-example/public/1.png -------------------------------------------------------------------------------- /ui/ssr-example/public/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/ssr-example/public/2.png -------------------------------------------------------------------------------- /ui/ssr-example/public/clock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/ssr-example/public/clock.png -------------------------------------------------------------------------------- /ui/ssr-example/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/ssr-example/public/favicon.ico -------------------------------------------------------------------------------- /ui/ssr-example/public/flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/ssr-example/public/flag.png -------------------------------------------------------------------------------- /ui/ssr-example/public/target.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/ssr-example/public/target.jpg -------------------------------------------------------------------------------- /ui/ssr-example/src/client/common/AutoInjectProps.tsx: -------------------------------------------------------------------------------- 1 | import { memo } from "react"; 2 | 3 | import { useGetInitialProps } from "../hooks"; 4 | 5 | import type { ComponentType } from "react"; 6 | 7 | export const AutoInjectProps = (Component: ComponentType, path = "/") => { 8 | const MemoComponent = memo(Component); 9 | 10 | const RouterComponentWithProps = () => { 11 | const props = useGetInitialProps(path); 12 | 13 | return ; 14 | }; 15 | 16 | return RouterComponentWithProps; 17 | }; 18 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/common/LoadingBar/index.module.scss: -------------------------------------------------------------------------------- 1 | .loadingBar { 2 | position: fixed; 3 | top: 0; 4 | left: 0; 5 | width: 100%; 6 | z-index: 9999; 7 | transform-origin: 0 0; 8 | background-color: palevioletred; 9 | } 10 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/common/LoadingBar/index.tsx: -------------------------------------------------------------------------------- 1 | import { useLoading, useLoadingBar } from "@client/hooks"; 2 | 3 | import { Bar } from "./LoadingBar"; 4 | 5 | import type { LoadingBarWrapperType } from "@client/types/common"; 6 | 7 | export const LoadingBar: LoadingBarWrapperType = () => { 8 | const loading = useLoading((state) => state.loading); 9 | const { ref } = useLoadingBar({ loading }); 10 | 11 | return ; 12 | }; 13 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/Arrow.tsx: -------------------------------------------------------------------------------- 1 | import { memo } from "react"; 2 | 3 | const _Arrow = ({ className }: { className: string }) => { 4 | return ( 5 | 6 | 7 | 8 | ); 9 | }; 10 | 11 | export const Arrow = memo(_Arrow); 12 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/Card/index.tsx: -------------------------------------------------------------------------------- 1 | import { forwardRef, Box } from "@chakra-ui/react"; 2 | 3 | import type { BoxProps } from "@chakra-ui/react"; 4 | 5 | export const Card = forwardRef(({ children, ...boxProps }, ref) => { 6 | return ( 7 | 8 | {children} 9 | 10 | ); 11 | }); 12 | 13 | Card.displayName = "Card"; 14 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/ColorMode/index.tsx: -------------------------------------------------------------------------------- 1 | import { Button, Icon, useColorMode } from "@chakra-ui/react"; 2 | import { SunIcon, MoonIcon } from "lucide-react"; 3 | 4 | export const ColorMode = () => { 5 | const { colorMode, toggleColorMode } = useColorMode(); 6 | return ( 7 | 10 | ); 11 | }; 12 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/Comment/index.tsx: -------------------------------------------------------------------------------- 1 | import { Divider } from "@chakra-ui/react"; 2 | 3 | import { Item } from "./Item"; 4 | 5 | import type { GetSingleBlogQuery } from "@site/graphql"; 6 | 7 | export const Comment = ({ data }: { data: GetSingleBlogQuery["repository"]["issue"]["comments"]["nodes"] }) => { 8 | return ( 9 | <> 10 | {data.length > 0 && } 11 | {data.map((p) => ( 12 | 13 | ))} 14 | 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/Error/index.tsx: -------------------------------------------------------------------------------- 1 | import { useToast } from "@chakra-ui/react"; 2 | import React, { useEffect } from "react"; 3 | 4 | import type { ApolloError } from "@apollo/client"; 5 | 6 | export const ErrorCom = ({ error }: { error: ApolloError }) => { 7 | const open = useToast(); 8 | 9 | useEffect(() => { 10 | open({ 11 | title: "Get Blog Error", 12 | description: error.message, 13 | status: "error", 14 | }); 15 | }, [error, open]); 16 | 17 | return ; 18 | }; 19 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/Follower/index.tsx: -------------------------------------------------------------------------------- 1 | import { memo } from "react"; 2 | 3 | import { Follower } from "./Item"; 4 | 5 | import type { GetViewerQuery } from "@site/graphql"; 6 | 7 | const _Followers = ({ data }: { data: GetViewerQuery["viewer"]["followers"]["nodes"] }) => ( 8 | <> 9 | {data.map(({ login, name, avatarUrl, id, email, bioHTML }, index) => { 10 | return ; 11 | })} 12 | 13 | ); 14 | 15 | export const Followers = memo(_Followers); 16 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/GridLayout/index.tsx: -------------------------------------------------------------------------------- 1 | import { styled } from "@chakra-ui/react"; 2 | import { WidthProvider, Responsive } from "react-grid-layout"; 3 | 4 | const ResponsiveReactGridLayout = WidthProvider(Responsive); 5 | 6 | export const StyledResponsiveReactGridLayout = styled(ResponsiveReactGridLayout); 7 | 8 | export const ReactGridLayout = Responsive; 9 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/Hover/index.tsx: -------------------------------------------------------------------------------- 1 | import { Box, forwardRef } from "@chakra-ui/react"; 2 | 3 | import type { BoxProps } from "@chakra-ui/react"; 4 | 5 | export const Hover = forwardRef(({ children, transform, ...props }, ref) => { 6 | return ( 7 | 19 | {children} 20 | 21 | ); 22 | }); 23 | 24 | Hover.displayName = "Hover"; 25 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/Icons/Webpack.tsx: -------------------------------------------------------------------------------- 1 | export const Webpack = (props) => { 2 | return ( 3 | 4 | 8 | 9 | 10 | ); 11 | }; 12 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/Icons/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./LeetCode"; 2 | export * from "./Webpack"; 3 | export * from "./Vite"; 4 | export * from "./Rspack"; 5 | export * from "./NextJs"; 6 | export * from "./Remix"; 7 | export * from "./ReactRouter"; 8 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/LockBody/index.tsx: -------------------------------------------------------------------------------- 1 | import { RemoveScroll } from "react-remove-scroll"; 2 | 3 | import { useLockBodyCount } from "@client/hooks"; 4 | 5 | export const LockBody = () => { 6 | const count = useLockBodyCount(); 7 | 8 | return ( 9 | 0} className="placeholder" as="span"> 10 | <> 11 | 12 | ); 13 | }; 14 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/ModuleManager/DesktopOverlay.tsx: -------------------------------------------------------------------------------- 1 | import { useOverlayArray } from "@client/hooks"; 2 | 3 | import { Desktop } from "../Overlay"; 4 | 5 | export const DesktopOverlay = () => { 6 | const { desktop: overlays } = useOverlayArray() || {}; 7 | 8 | return <>{overlays?.map((p) => )}; 9 | }; 10 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/ModuleManager/MobileOverlay.tsx: -------------------------------------------------------------------------------- 1 | import { AnimatePresence } from "framer-motion"; 2 | 3 | import { useOverlayArray } from "@client/hooks"; 4 | 5 | import { Mobile } from "../Overlay"; 6 | 7 | export const MobileOverlay = () => { 8 | const { mobile: overlays } = useOverlayArray() || {}; 9 | return ( 10 | <> 11 | {/* currently the exit animation not work, look like it is a bug, SEE https://github.com/framer/motion/issues/1085, https://github.com/framer/motion/issues/1424 */} 12 | {overlays?.map((p) => (p.showState ? : null))} 13 | 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/Overlay/index.ts: -------------------------------------------------------------------------------- 1 | export { Mobile } from "./Mobile"; 2 | export { Desktop } from "./Desktop"; 3 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/ScrollControl/ScrollControlContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext, useContext } from "react"; 2 | 3 | export const ScrollControlContext = createContext({ 4 | totalSection: 0, 5 | currentSection: 0, 6 | setTotalSection: (_length: number): void => void 0, 7 | setCurrentSection: (_index: number): void => void 0, 8 | onNextSection: (): void => void 0, 9 | onPrevSection: (): void => void 0, 10 | }); 11 | 12 | export const useScrollControl = () => useContext(ScrollControlContext); 13 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/ScrollControl/ScrollSectionContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext, useContext } from "react"; 2 | 3 | import type { RefObject } from "react"; 4 | 5 | export const ScrollSectionContext = createContext<{ ref: RefObject }>({ ref: { current: null } }); 6 | 7 | export const useScrollSection = () => useContext(ScrollSectionContext); 8 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/ScrollControl/ScrollViewContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext, useContext } from "react"; 2 | 3 | export const ScrollViewContext = createContext({ 4 | inViewArray: [] as boolean[], 5 | setCurrentView: (_inView: boolean, _index: number): void => void 0, 6 | }); 7 | 8 | export const useScrollView = () => useContext(ScrollViewContext); 9 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/ScrollControl/index.ts: -------------------------------------------------------------------------------- 1 | export { ScrollControl } from "./ScrollControl"; 2 | export { ScrollContent } from "./ScrollContent"; 3 | export { ScrollSection } from "./ScrollSection"; 4 | export { ScrollToTop } from "./ScrollToTop"; 5 | export { ScrollControlTool } from "./ScrollControlTool"; 6 | export { useScrollSection } from "./ScrollSectionContext"; 7 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/Table/BaseTable.tsx: -------------------------------------------------------------------------------- 1 | import { Table, TableContainer } from "@chakra-ui/react"; 2 | 3 | import type { TableProps } from "@chakra-ui/react"; 4 | 5 | export const BaseTable = ({ ...restProps }: TableProps) => ( 6 | 7 | 8 | 9 | ); 10 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/Table/Td.tsx: -------------------------------------------------------------------------------- 1 | import { Td as OriginalTd } from "@chakra-ui/react"; 2 | 3 | import { ErrorCatch } from "./ErrorCatch"; 4 | 5 | import type { TableCellProps } from "@chakra-ui/react"; 6 | 7 | export const Td = (props: TableCellProps) => { 8 | const { children, ...resProps } = props; 9 | return ( 10 | 11 | {children} 12 | 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/Table/useSkeleton.tsx: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | 3 | export const useSkeleton = (hasData: any, skeletonRowCount = 0) => { 4 | const skeletonRows = useMemo(() => new Array(skeletonRowCount).fill(null), [skeletonRowCount]); 5 | return { 6 | skeletonRows, 7 | skeletonVisible: !hasData, 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/component/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Section"; 2 | export * from "./Table"; 3 | export * from "./ScrollControl"; 4 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/config/container.ts: -------------------------------------------------------------------------------- 1 | export const CONTAINER_WIDTH = 1580; 2 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/config/gridLayout.ts: -------------------------------------------------------------------------------- 1 | export const GRID_ROW_HEIGHT = 10; 2 | export const DRAG_HANDLER_SELECTOR = "drag-able-item"; 3 | export const DISABLE_DRAG_HANDLER_SELECTOR = "ignore-drag-able-item"; 4 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/config/source.ts: -------------------------------------------------------------------------------- 1 | export const BLOG_SOURCE = "https://github.com/facebook/react/issues"; 2 | export const BLOG_REPOSITORY = "react"; 3 | export const BLOG_REPOSITORY_OWNER = "facebook"; 4 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/container/Section/index.ts: -------------------------------------------------------------------------------- 1 | export { MainSection } from "./Main"; 2 | export { ApiSection } from "./Api"; 3 | export { DevToolSection } from "./DevTool"; 4 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./useLang"; 2 | export * from "./useFoot"; 3 | export * from "./useSize"; 4 | export * from "./useUpdate"; 5 | export * from "./usePreLoad"; 6 | export * from "./useOverlay"; 7 | export * from "./useIsMobile"; 8 | export * from "./useIsMounted"; 9 | export * from "./useLoadingBar"; 10 | export * from "./useEffectOnce"; 11 | export * from "./useWindowSize"; 12 | export * from "./useLoadingStore"; 13 | export * from "./useLockBodyScroll"; 14 | export * from "./useDebouncedState"; 15 | export * from "./useGetInitialProps"; 16 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/hooks/useDebouncedState.ts: -------------------------------------------------------------------------------- 1 | import debounce from "lodash/debounce"; 2 | import { useMemo, useState } from "react"; 3 | 4 | import type { Dispatch, SetStateAction } from "react"; 5 | 6 | export const useDebouncedState = (initialState: T | (() => T), time = 200): [T, Dispatch>] => { 7 | const [state, setState] = useState(initialState); 8 | 9 | const setDebounceState = useMemo(() => debounce(setState, time), [time]); 10 | 11 | return [state, setDebounceState]; 12 | }; 13 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/hooks/useDevTool.ts: -------------------------------------------------------------------------------- 1 | import { createState } from "reactivity-store"; 2 | 3 | export const useDevTool = createState(() => ({ open: false }), { withActions: (s) => ({ toggle: () => (s.open = !s.open) }) }); 4 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/hooks/useEffectOnce.ts: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react"; 2 | 3 | export const useEffectOnce = (fn: () => unknown) => { 4 | useEffect(() => { 5 | fn(); 6 | // eslint-disable-next-line react-hooks/exhaustive-deps 7 | }, []); 8 | }; 9 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/hooks/useFoot.ts: -------------------------------------------------------------------------------- 1 | import { createState } from "reactivity-store"; 2 | 3 | export const useFoot = createState(() => ({ state: true }), { 4 | withActions: (s: { state: boolean }) => ({ enable: () => (s.state = true), disable: () => (s.state = false) }), 5 | withNamespace: "useFoot", 6 | }); 7 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/hooks/useGetInitialProps.ts: -------------------------------------------------------------------------------- 1 | import { useAppSelector } from "@shared"; 2 | 3 | import { preLoadPropsKey } from "../utils"; 4 | 5 | export const useGetInitialProps = (pagePath: string) => { 6 | const routerData = useAppSelector((state) => state.client.clientProps.data); 7 | 8 | const propsKey = preLoadPropsKey(pagePath); 9 | 10 | return routerData[propsKey]; 11 | }; 12 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/hooks/useHead.ts: -------------------------------------------------------------------------------- 1 | import { createState } from "reactivity-store"; 2 | 3 | export const useHead = createState(() => ({ state: true }), { 4 | withActions: (s: { state: boolean }) => ({ enable: () => (s.state = true), disable: () => (s.state = false) }), 5 | withNamespace: "useHead", 6 | }); 7 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/hooks/useIsMobile.ts: -------------------------------------------------------------------------------- 1 | import { useBreakpointValue } from "@chakra-ui/react"; 2 | 3 | export const useIsMobile = () => { 4 | return useBreakpointValue({ base: true, lg: false }, { ssr: true }); 5 | }; 6 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/hooks/useIsMounted.ts: -------------------------------------------------------------------------------- 1 | import { useState, useEffect, startTransition } from "react"; 2 | 3 | export const useIsMounted = () => { 4 | const [mounted, setMounted] = useState(false); 5 | 6 | useEffect(() => { 7 | startTransition(() => { 8 | setMounted(true); 9 | }); 10 | }, []); 11 | 12 | return mounted; 13 | }; 14 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/hooks/useLoadingStore.ts: -------------------------------------------------------------------------------- 1 | import { createState, withActions } from "reactivity-store"; 2 | 3 | export const useLoading = createState( 4 | withActions(() => ({ loading: false }), { 5 | generateActions: (state) => ({ 6 | setLoading: (s: boolean) => { 7 | state.loading = s; 8 | }, 9 | }), 10 | }), 11 | { 12 | withNamespace: "useLoading", 13 | withDeepSelector: false, 14 | } 15 | ); 16 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/hooks/useMainCard.ts: -------------------------------------------------------------------------------- 1 | import { createState } from "reactivity-store"; 2 | 3 | export const useMainCard = createState(() => ({ drag: false }), { 4 | withActions: (s: { drag: boolean }) => ({ onDragStart: () => (s.drag = true), onDragEnd: () => (s.drag = false) }), 5 | withNamespace: "useMainCard", 6 | }); 7 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/hooks/useUpdate.ts: -------------------------------------------------------------------------------- 1 | import { useReducer } from "react"; 2 | 3 | export const useUpdate = () => { 4 | const [, update] = useReducer((p) => p + 1, 0); 5 | 6 | return update; 7 | }; 8 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/hooks/useWindowSize.ts: -------------------------------------------------------------------------------- 1 | import { isBrowser } from "framer-motion"; 2 | import { useEffect } from "react"; 3 | 4 | import { useDebouncedState } from "./useDebouncedState"; 5 | 6 | export const useWindowSize = () => { 7 | const [state, setState] = useDebouncedState({ 8 | height: isBrowser ? window.innerHeight : 0, 9 | width: isBrowser ? window.innerHeight : 0, 10 | }); 11 | 12 | useEffect(() => { 13 | const resize = () => setState({ height: window.innerHeight, width: window.innerWidth }); 14 | 15 | resize(); 16 | 17 | window.addEventListener("resize", resize, { passive: true }); 18 | 19 | return window.removeEventListener("reset", resize); 20 | }, [setState]); 21 | 22 | return state; 23 | }; 24 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/pages/404.tsx: -------------------------------------------------------------------------------- 1 | import { Box, useToast } from "@chakra-ui/react"; 2 | import { useEffect } from "react"; 3 | import { useNavigate } from "react-router"; 4 | 5 | import { noBase } from "@shared"; 6 | 7 | export default function Index() { 8 | const navigate = useNavigate(); 9 | const open = useToast(); 10 | 11 | useEffect(() => { 12 | open({ 13 | title: "404", 14 | description: "404 not found, redirect to home page", 15 | status: "error", 16 | }); 17 | navigate(noBase ? "/" : `/${__BASENAME__}/`); 18 | }, [open, navigate]); 19 | 20 | return ; 21 | } 22 | 23 | export const isStatic = true; 24 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/router/dynamicRoutes.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable prettier/prettier */ 2 | /* do not editor this template */ 3 | import type { DynamicRouteConfig } from "@client/types/route"; 4 | 5 | export const dynamicRouteConfig: DynamicRouteConfig[] = [{"path":"/About","componentPath":"About"},{"path":"/Blog","componentPath":"Blog"},{"path":"/Excalidraw","componentPath":"Excalidraw"},{"path":"/","componentPath":"index"},{"path":"/*","componentPath":"404"}]; -------------------------------------------------------------------------------- /ui/ssr-example/src/client/router/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./routes"; 2 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/router/routes.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-var-requires 2 | export const allRoutes = __STREAM__ ? require("./routers.stream").allRoutes : require("./routers.loadable").allRoutes; 3 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/store/Time.ts: -------------------------------------------------------------------------------- 1 | import dayjs from "dayjs"; 2 | import { createStoreWithComponent, onMounted, onUnmounted, ref } from "reactivity-store"; 3 | 4 | export const Time = createStoreWithComponent({ 5 | setup: () => { 6 | const time = ref(dayjs().format("YYYY-MM-DD HH:mm:ss")); 7 | 8 | const isMount = ref(false); 9 | 10 | let id = null; 11 | 12 | onMounted(() => { 13 | id = setInterval(() => { 14 | time.value = dayjs().format("YYYY-MM-DD HH:mm:ss"); 15 | }, 1000); 16 | }); 17 | 18 | onMounted(() => { 19 | isMount.value = true; 20 | }); 21 | 22 | onUnmounted(() => { 23 | clearInterval(id); 24 | }); 25 | 26 | return { time, isMount }; 27 | }, 28 | }); 29 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/store/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Time"; 2 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/types/hooks.ts: -------------------------------------------------------------------------------- 1 | import type { PreLoadRouteConfig } from "./route"; 2 | import type { preLoad } from "../utils"; 3 | import type { useLocation } from "react-router"; 4 | 5 | interface UsePreLoadProps { 6 | routes: PreLoadRouteConfig[]; 7 | preLoad: typeof preLoad; 8 | } 9 | export interface UsePreLoadType { 10 | (props: UsePreLoadProps): { 11 | loaded?: { 12 | location: ReturnType; 13 | query: URLSearchParams; 14 | }; 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/types/util.ts: -------------------------------------------------------------------------------- 1 | /* delay */ 2 | interface Cancel { 3 | (key: string): void; 4 | } 5 | interface Delay { 6 | (time: number, action?: () => T, key?: string): Promise; 7 | } 8 | interface TimeoutMap { 9 | [props: string]: Array; 10 | } 11 | interface ReJectMap { 12 | [props: string]: Array<(() => void) | void>; 13 | } 14 | interface KeyMap { 15 | [props: string]: number; 16 | } 17 | 18 | export type { Cancel, Delay, TimeoutMap, ReJectMap, KeyMap }; 19 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/utils/cx.ts: -------------------------------------------------------------------------------- 1 | export const cx = (...classNames: any[]) => { 2 | const allClassNames = classNames.filter(Boolean).filter((c) => typeof c === "string") as string[]; 3 | const classNamesSet = allClassNames 4 | .map((c) => c.split(" ")) 5 | .reduce>((p, c) => { 6 | c.forEach((_c) => p.add(_c)); 7 | return p; 8 | }, new Set()); 9 | return new Array(...classNamesSet).join(" "); 10 | }; 11 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./delay"; 2 | export * from "./preLoad"; 3 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/utils/log.ts: -------------------------------------------------------------------------------- 1 | const isBrowser = typeof window !== "undefined"; 2 | 3 | const side = isBrowser ? "client" : "server"; 4 | 5 | export const log = (message: string | Error, lev: "normal" | "warn" | "error") => { 6 | if (lev === "error") { 7 | if (message instanceof Error) { 8 | console.log(`[${side}]`, `[error]`, message.stack); 9 | } else { 10 | console.log(`[${side}]`, `[error]`, message.toString()); 11 | } 12 | } else if (lev === "warn") { 13 | console.log(`[${side}]`, `[warn]`, message.toString()); 14 | } else { 15 | if (process.env.NODE_ENV === "development") { 16 | console.log(`[${side}]`, `[normal]`, message.toString()); 17 | } 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /ui/ssr-example/src/client/utils/time.ts: -------------------------------------------------------------------------------- 1 | import dayjs from "dayjs"; 2 | import "dayjs/locale/zh-cn"; 3 | import calendarPlugin from "dayjs/plugin/calendar"; 4 | import relativeTime from "dayjs/plugin/relativeTime"; 5 | 6 | import { log } from "./log"; 7 | 8 | dayjs.locale("zh-cn"); 9 | dayjs.extend(relativeTime); 10 | dayjs.extend(calendarPlugin); 11 | 12 | const momentTo = (time: string | Date) => { 13 | if (typeof time === "string") { 14 | time = new Date(time); 15 | } 16 | if (time instanceof Date) { 17 | return dayjs(new Date()).to(dayjs(time)); 18 | } else { 19 | log(`time parameter error : ${time}`, "error"); 20 | return dayjs().toNow(); 21 | } 22 | }; 23 | 24 | export { momentTo, dayjs }; 25 | -------------------------------------------------------------------------------- /ui/ssr-example/src/server/api/index.ts: -------------------------------------------------------------------------------- 1 | import { apiHandler } from "./lang"; 2 | 3 | import type { Express } from "express"; 4 | 5 | export const setApi = (app: Express) => { 6 | app.use("/api", apiHandler); 7 | }; 8 | -------------------------------------------------------------------------------- /ui/ssr-example/src/server/app.ts: -------------------------------------------------------------------------------- 1 | import { wrapperMiddlewareRequest } from "./middleware/apiHandler"; 2 | import { render } from "./middleware/render"; 3 | import { renderError } from "./middleware/renderError"; 4 | 5 | export const generateHandler = () => 6 | wrapperMiddlewareRequest({ 7 | requestHandler: render, 8 | errorHandler: ({ req, res, code, e }) => renderError({ req, res, e, code }), 9 | }); 10 | -------------------------------------------------------------------------------- /ui/ssr-example/src/server/middleware/develop/index.ts: -------------------------------------------------------------------------------- 1 | import { webpackMiddleware } from "./webpackMiddleware"; 2 | 3 | import type { Express } from "express"; 4 | 5 | export const develop = async (app: Express) => { 6 | await webpackMiddleware(app); 7 | }; 8 | -------------------------------------------------------------------------------- /ui/ssr-example/src/server/middleware/render.ts: -------------------------------------------------------------------------------- 1 | import { getIsSSR } from "@shared"; 2 | 3 | import { renderSSR, renderCSR, renderStreamSSR } from "./renderPage"; 4 | 5 | import type { RenderType } from "../type"; 6 | 7 | // 渲染函数 8 | const render: RenderType = async ({ req, res }) => { 9 | const { isSSR } = req.query; 10 | if (isSSR || getIsSSR()) { 11 | if (__STREAM__) { 12 | await renderStreamSSR({ req, res }); 13 | } else { 14 | await renderSSR({ req, res }); 15 | } 16 | } else { 17 | await renderCSR({ req, res }); 18 | } 19 | }; 20 | 21 | export { render }; 22 | -------------------------------------------------------------------------------- /ui/ssr-example/src/server/middleware/renderPage/middleware/index.ts: -------------------------------------------------------------------------------- 1 | export { generateGlobalEnv } from "./globalEnv"; 2 | export { initLang } from "./initLang"; 3 | export { initStore } from "./initStore"; 4 | export { loadStore } from "./loadStore"; 5 | export { loadLang } from "./loadLang"; 6 | export { loadAsset } from "./loadAsset"; 7 | -------------------------------------------------------------------------------- /ui/ssr-example/src/server/middleware/renderPage/middleware/initLang.ts: -------------------------------------------------------------------------------- 1 | import { RenderError } from "@server/util/renderError"; 2 | import { defaultLang } from "@shared"; 3 | 4 | import type { Middleware } from "../compose"; 5 | 6 | export const initLang: Middleware = (next) => async (args) => { 7 | const { env } = args; 8 | if (!env) { 9 | throw new RenderError("env 没有初始化", 5000); 10 | } 11 | const { req, res } = args; 12 | 13 | const cookieLang = req.cookies?.site_lang; 14 | 15 | const lang = cookieLang || defaultLang; 16 | 17 | res.cookie("site_lang", lang); 18 | 19 | args.lang = lang; 20 | 21 | env["LANG"] = lang; 22 | 23 | await next(args); 24 | }; 25 | -------------------------------------------------------------------------------- /ui/ssr-example/src/server/middleware/renderPage/middleware/initStore.ts: -------------------------------------------------------------------------------- 1 | import { createUniversalStore } from "@shared"; 2 | 3 | import type { Middleware } from "../compose"; 4 | 5 | export const initStore: Middleware = (next) => async (args) => { 6 | const store = createUniversalStore(); 7 | 8 | args.store = store; 9 | 10 | await next(args); 11 | }; 12 | -------------------------------------------------------------------------------- /ui/ssr-example/src/server/middleware/renderPage/middleware/loadLang.ts: -------------------------------------------------------------------------------- 1 | import { RenderError } from "@server/util/renderError"; 2 | import { loadCurrentLang, supportedLang } from "@shared"; 3 | 4 | import type { Middleware } from "../compose"; 5 | 6 | export const loadLang: Middleware = (next) => async (args) => { 7 | const { store, lang } = args; 8 | if (!store || !lang) { 9 | throw new RenderError("store or lang 初始化失败", 500); 10 | } 11 | if (!supportedLang[lang as keyof typeof supportedLang]) { 12 | throw new RenderError("不支持的语言", 404); 13 | } 14 | 15 | await loadCurrentLang(store.dispatch, lang as keyof typeof supportedLang); 16 | 17 | await next(args); 18 | }; 19 | -------------------------------------------------------------------------------- /ui/ssr-example/src/server/static/index.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | 3 | import { getStaticPageManifest } from "./util"; 4 | 5 | import type { Express } from "express"; 6 | 7 | export const page = (app: Express) => { 8 | if (!__DEVELOPMENT__) { 9 | app.use(async (req, res, next) => { 10 | // should refresh and cache when some usage 11 | const staticPageManifest = await getStaticPageManifest().catch(() => null); 12 | const fileName = staticPageManifest?.[`.${req.path}`]; 13 | if (fileName) { 14 | const stream = fs.createReadStream(fileName); 15 | res.setHeader("content-type", "text/html"); 16 | stream.pipe(res); 17 | } else { 18 | next(); 19 | } 20 | }); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /ui/ssr-example/src/server/static/util.ts: -------------------------------------------------------------------------------- 1 | import { getAllStateFileContent, manifestStaticPageFile } from "../util/webpackManifest"; 2 | 3 | export const getStaticPageManifest = () => getAllStateFileContent(manifestStaticPageFile("client")); 4 | -------------------------------------------------------------------------------- /ui/ssr-example/src/server/util/loadableManifest.ts: -------------------------------------------------------------------------------- 1 | import { MANIFEST } from "@site/webpack"; 2 | import path from "path"; 3 | 4 | const outputPath = (env: "server" | "client"): string => (__DEVELOPMENT__ ? path.resolve(process.cwd(), "dev", env) : path.resolve(process.cwd(), "dist", env)); 5 | 6 | export const manifestLoadableFile = (env: "server" | "client"): string => path.resolve(outputPath(env), MANIFEST.manifest_loadable); 7 | -------------------------------------------------------------------------------- /ui/ssr-example/src/server/util/renderError.ts: -------------------------------------------------------------------------------- 1 | export class RenderError extends Error { 2 | constructor( 3 | message: string, 4 | readonly code: number 5 | ) { 6 | super(message); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ui/ssr-example/src/server/util/serverLog.ts: -------------------------------------------------------------------------------- 1 | import { pino } from "pino"; 2 | import pretty from "pino-pretty"; 3 | 4 | export const serverLog = (msg: string, level: "info" | "warn" | "error") => pino(pretty())[level](`[server] ${msg}`); 5 | -------------------------------------------------------------------------------- /ui/ssr-example/src/shared/emotionCache.ts: -------------------------------------------------------------------------------- 1 | import createCache from "@emotion/cache"; 2 | 3 | export const createEmotionCache = () => createCache({ key: "css" }); 4 | -------------------------------------------------------------------------------- /ui/ssr-example/src/shared/i18n.ts: -------------------------------------------------------------------------------- 1 | import { serverActionName } from "./store/action"; 2 | import { getDataAction_Server } from "./store/reducer"; 3 | 4 | import type { AppDispatch } from "./store"; 5 | 6 | export const supportedLang = { 7 | en: "English", 8 | zh: "中文", 9 | }; 10 | 11 | export const loadCurrentLang = async (dispatch: AppDispatch, lang: keyof typeof supportedLang) => { 12 | await dispatch(getDataAction_Server({ name: serverActionName.serverLang, lang })); 13 | }; 14 | 15 | export const defaultLang = "en"; 16 | -------------------------------------------------------------------------------- /ui/ssr-example/src/shared/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./env"; 2 | export * from "./i18n"; 3 | export * from "./store"; 4 | export * from "./theme"; 5 | export * from "./template"; 6 | export * from "./safeData"; 7 | export * from "./emotionCache"; 8 | -------------------------------------------------------------------------------- /ui/ssr-example/src/shared/safeData.ts: -------------------------------------------------------------------------------- 1 | export const safeData = >(data: T, key?: string): T => { 2 | if (key) { 3 | const cacheData = data[key]; 4 | Object.defineProperty(data, key, { 5 | get: function () { 6 | return cacheData; 7 | }, 8 | configurable: false, 9 | }); 10 | return data; 11 | } else { 12 | Object.keys(data).forEach((key) => { 13 | const cacheData = data[key]; 14 | Object.defineProperty(data, key, { 15 | get: function () { 16 | return cacheData; 17 | }, 18 | configurable: false, 19 | }); 20 | }); 21 | return data; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /ui/ssr-example/src/shared/store/action.ts: -------------------------------------------------------------------------------- 1 | export enum clientActionName { 2 | clientLang = "clientLang", 3 | clientProps = "clientProps", 4 | } 5 | 6 | export enum serverActionName { 7 | serverLang = "serverLang", 8 | } 9 | -------------------------------------------------------------------------------- /ui/ssr-example/src/shared/store/reducer/client/action/index.ts: -------------------------------------------------------------------------------- 1 | export { clientLangReducer } from "./clientLang"; 2 | export { clientPropsReducer } from "./clientProps"; 3 | -------------------------------------------------------------------------------- /ui/ssr-example/src/shared/store/reducer/client/index.ts: -------------------------------------------------------------------------------- 1 | import { combineReducers } from "redux"; 2 | 3 | import { clientActionName } from "@shared/store/action"; 4 | 5 | import { clientLangReducer, clientPropsReducer } from "./action"; 6 | 7 | export const client = combineReducers({ 8 | [clientActionName.clientLang]: clientLangReducer, 9 | [clientActionName.clientProps]: clientPropsReducer, 10 | }); 11 | 12 | export * from "./share/action"; 13 | -------------------------------------------------------------------------------- /ui/ssr-example/src/shared/store/reducer/index.ts: -------------------------------------------------------------------------------- 1 | import { combineReducers } from "redux"; 2 | 3 | import { client } from "./client"; 4 | import { server } from "./server"; 5 | 6 | export const rootReducer = combineReducers({ 7 | client, 8 | server, 9 | }); 10 | 11 | export * from "./client"; 12 | 13 | export * from "./server"; 14 | -------------------------------------------------------------------------------- /ui/ssr-example/src/shared/store/reducer/server/action/index.ts: -------------------------------------------------------------------------------- 1 | export { serverLangReducer } from "./serverLang"; 2 | -------------------------------------------------------------------------------- /ui/ssr-example/src/shared/store/reducer/server/index.ts: -------------------------------------------------------------------------------- 1 | import { combineReducers } from "redux"; 2 | 3 | import { serverActionName } from "@shared/store/action"; 4 | 5 | import { serverLangReducer } from "./action"; 6 | 7 | export const server = combineReducers({ 8 | [serverActionName.serverLang]: serverLangReducer, 9 | }); 10 | 11 | export * from "./share/action"; 12 | -------------------------------------------------------------------------------- /ui/ssr-example/src/shared/store/saga/action/index.ts: -------------------------------------------------------------------------------- 1 | export { langSaga } from "./langSaga"; 2 | -------------------------------------------------------------------------------- /ui/ssr-example/src/shared/store/saga/index.ts: -------------------------------------------------------------------------------- 1 | import { all, takeLatest } from "redux-saga/effects"; 2 | 3 | import { serverActionName } from "../action"; 4 | import { serverAction } from "../reducer"; 5 | 6 | import { langSaga } from "./action"; 7 | 8 | type StartActionType = { type: ReturnType; done: () => void; [props: string]: any }; 9 | 10 | function* rootSaga() { 11 | yield all([takeLatest(serverAction.GET_DATA_ACTION(serverActionName.serverLang), ({ done, lang }) => langSaga({ done, lang }))]); 12 | } 13 | 14 | export { rootSaga }; 15 | -------------------------------------------------------------------------------- /ui/ssr-example/src/shared/template/Body.tsx: -------------------------------------------------------------------------------- 1 | import { ColorModeScript } from "@chakra-ui/react"; 2 | 3 | import type { HTMLProps } from "."; 4 | 5 | export const Body = ({ children, script = [], refresh = [] }: HTMLProps) => ( 6 | 7 | 8 | {typeof children === "string" ?
    :
    {children}
    } 9 | {script.filter(Boolean).map((ele) => ele)} 10 | {refresh.filter(Boolean).map((ele) => ele)} 11 | 12 | ); 13 | -------------------------------------------------------------------------------- /ui/ssr-example/src/shared/theme/index.ts: -------------------------------------------------------------------------------- 1 | import { extendTheme } from "@chakra-ui/react"; 2 | 3 | import { semanticTokens } from "./semanticTokens"; 4 | import { styles } from "./styles"; 5 | 6 | import type { ChakraTheme } from "@chakra-ui/react"; 7 | 8 | export const theme: Partial = extendTheme({ 9 | styles, 10 | semanticTokens, 11 | fonts: { 12 | heading: "Josefin Sans", 13 | body: "Josefin Sans", 14 | mono: "Josefin Sans", 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /ui/ssr-example/src/shared/theme/styles.ts: -------------------------------------------------------------------------------- 1 | import type { ChakraTheme } from "@chakra-ui/react"; 2 | 3 | export const styles: ChakraTheme["styles"] = { 4 | global: {}, 5 | }; 6 | -------------------------------------------------------------------------------- /ui/vite-example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vite + @my-react 7 | 8 | 9 | 10 |
    11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ui/vite-example/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/vite-example/public/favicon.ico -------------------------------------------------------------------------------- /ui/vite-example/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import './index.css' 4 | import App from './App.tsx' 5 | 6 | createRoot(document.getElementById('root')!).render( 7 | 8 | 9 | , 10 | ) -------------------------------------------------------------------------------- /ui/vite-example/src/vite.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /ui/vite-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ] 7 | } -------------------------------------------------------------------------------- /ui/vite-example/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 | }, 23 | "include": ["vite.config.ts"] 24 | } -------------------------------------------------------------------------------- /ui/vite-ssr-example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vite + @my-react + ssr 7 | 8 | 9 | 10 |
    11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ui/vite-ssr-example/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrWangJustToDo/MyReact/5ec8cc69f73a458fe64cde49e6af0bff666fd660/ui/vite-ssr-example/public/favicon.ico -------------------------------------------------------------------------------- /ui/vite-ssr-example/src/entry-client.tsx: -------------------------------------------------------------------------------- 1 | import { hydrateRoot } from "react-dom/client"; 2 | import { BrowserRouter } from "react-router-dom"; 3 | 4 | import { App } from "./App"; 5 | import "./index.css"; 6 | 7 | hydrateRoot( 8 | document.getElementById("root")!, 9 | 10 | 11 | 12 | ); 13 | -------------------------------------------------------------------------------- /ui/vite-ssr-example/src/entry-server.tsx: -------------------------------------------------------------------------------- 1 | import { renderToString } from "react-dom/server"; 2 | import { StaticRouter } from "react-router-dom/server"; 3 | 4 | import { App } from "./App"; 5 | 6 | export function render(url: string) { 7 | return renderToString( 8 | 9 | 10 | 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /ui/vite-ssr-example/src/page/Foo.tsx: -------------------------------------------------------------------------------- 1 | import { B } from "../components/B"; 2 | 3 | export default function Foo() { 4 | return ( 5 | <> 6 |
    Foo page
    7 | 8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /ui/vite-ssr-example/src/page/Home.tsx: -------------------------------------------------------------------------------- 1 | export default function Home() { 2 | return
    Home page
    ; 3 | } 4 | -------------------------------------------------------------------------------- /ui/vite-ssr-example/src/vite.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /ui/vite-ssr-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "Bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["src"], 24 | "references": [{ "path": "./tsconfig.node.json" }] 25 | } 26 | -------------------------------------------------------------------------------- /ui/vite-ssr-example/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | --------------------------------------------------------------------------------