Skip to content
This repository has been archived by the owner on Apr 7, 2023. It is now read-only.

Commit

Permalink
feat: add support for functional App
Browse files Browse the repository at this point in the history
  • Loading branch information
afflicted-cat committed Apr 20, 2021
1 parent 83d0c20 commit 8c2c985
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 28 deletions.
4 changes: 4 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
module.exports = {
root: true,
extends: ["@wowvendor/eslint-config-base", "@wowvendor/eslint-config-react", "@wowvendor/eslint-config-typescript"],
rules: {
"react/destructuring-assignment": "off",
"@typescript-eslint/no-explicit-any": "off",
},
};
2 changes: 1 addition & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export default {
sourcemap: true,
exports: "named",
file: pkg.main,
interop: false,
externalLiveBindings: false,
},
],
Expand All @@ -38,6 +37,7 @@ export default {
commonjs({ extensions }),
],
external: [
"next/app",
"effector/fork",
"effector-react/ssr",
...Object.keys(Object.assign({}, pkg.dependencies, pkg.peerDependencies)),
Expand Down
12 changes: 5 additions & 7 deletions src/lib/get-start-units.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { AppInitialProps } from "next/app";
import { Unit, is } from "effector";
import { is, Unit } from "effector";

import { AppType, Enhancer, RenderPage, PageContext } from "../types";
import { AppType, AppProps, Enhancer, RenderPage, PageContext } from "../types";

import { START_UNIT_KEY } from "./constants";

Expand All @@ -15,14 +14,13 @@ export function getStartUnits(originalRenderPage: RenderPage) {
return units.filter(is.unit);
}

function getStartUnit<P extends AppInitialProps>(units: StartUnits): Enhancer<AppType<P>> {
function getStartUnit<P extends AppProps>(units: StartUnits): Enhancer<AppType<P>> {
return () => (props) => {
if (START_UNIT_KEY in props) {
if (props?.[START_UNIT_KEY]) {
units.push(props[START_UNIT_KEY]);
}

// eslint-disable-next-line react/destructuring-assignment
if (START_UNIT_KEY in props.pageProps) {
if (props?.pageProps?.[START_UNIT_KEY]) {
units.push(props.pageProps[START_UNIT_KEY]);
}

Expand Down
8 changes: 2 additions & 6 deletions src/lib/render-page-with-scope.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import * as React from "react";
import { Provider } from "effector-react/ssr";
import { AppInitialProps } from "next/app";
import { Scope } from "effector/fork";

import { AppType, Enhancer, RenderPage } from "../types";
import { AppType, AppProps, Enhancer, RenderPage } from "../types";

export function renderPageWithScope(scope: Scope, originalRenderPage: RenderPage): RenderPage {
return (params) => {
Expand All @@ -20,10 +19,7 @@ export function renderPageWithScope(scope: Scope, originalRenderPage: RenderPage
};
}

function createEnhanceApp<P extends AppInitialProps>(
scope: Scope,
enhancer?: Enhancer<AppType<P>>,
): Enhancer<AppType<P>> {
function createEnhanceApp<P extends AppProps>(scope: Scope, enhancer?: Enhancer<AppType<P>>): Enhancer<AppType<P>> {
return (Component) => (props) => {
const App = enhancer ? enhancer(Component) : Component;

Expand Down
4 changes: 3 additions & 1 deletion src/types/extracted.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ import { NextComponentType } from "next";

export type Enhancer<C> = (Component: C) => C;
export type RenderPage = DocumentContext["renderPage"];
export type AppType<P extends AppInitialProps> = NextComponentType<AppContext, AppInitialProps, P>;
export type TargetComponentType<C> = NextComponentType<C, any, any>;
export type AppProps = AppInitialProps & { Component: NextComponentType };
export type AppType<P extends AppProps> = NextComponentType<AppContext, AppInitialProps, P>;
2 changes: 1 addition & 1 deletion src/with-fork.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ interface CustomDocumentProps extends DocumentProps {

export interface WithForkConfig {
debug?: boolean;
serializeIgnore?: Array<Store<unknown>>;
serializeIgnore?: Array<Store<any>>;
}

export function withFork({ debug, serializeIgnore }: WithForkConfig = {}) {
Expand Down
31 changes: 26 additions & 5 deletions src/with-hydrate.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import * as React from "react";
import NextApp, { AppProps } from "next/app";
import NextApp, { AppContext, AppProps } from "next/app";
import { hydrate } from "effector/fork";

import { domain } from "./domain";
import { INITIAL_STATE_KEY } from "./lib";
import { TargetComponentType } from "./types";

declare global {
interface Window {
Expand All @@ -12,13 +13,15 @@ declare global {
}
}

type HydratedApp = TargetComponentType<AppContext> & { origGetInitialProps?: never };

export function withHydrate() {
const isServer = typeof window === "undefined";

return (App: typeof NextApp) =>
class WithHydrateApp extends React.Component<AppProps> {
static origGetInitialProps = App.origGetInitialProps;
static getInitialProps = App.getInitialProps;
return (App: HydratedApp) => {
const WithHydrateApp = class WithHydrateApp extends React.Component<AppProps> {
static origGetInitialProps = App.origGetInitialProps || NextApp.origGetInitialProps;
static getInitialProps = NextApp.getInitialProps;

constructor(props: AppProps) {
super(props);
Expand All @@ -32,4 +35,22 @@ export function withHydrate() {
return <App {...this.props} />;
}
};

if (App.getInitialProps) {
WithHydrateApp.getInitialProps = async (ctx: any) => {
const [nextAppProps, hydratedAppProps] = await Promise.all([
NextApp.getInitialProps(ctx),
App.getInitialProps!(ctx),
]);

return {
...nextAppProps,
...hydratedAppProps,
pageProps: Object.assign({}, nextAppProps?.pageProps, hydratedAppProps?.pageProps),
};
};
}

return WithHydrateApp;
};
}
10 changes: 3 additions & 7 deletions src/with-start.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { NextPageContext, NextComponentType } from "next";
import { NextPageContext } from "next";
import { AppContext } from "next/app";
import { Unit } from "effector";

import { PageContext } from "./types";
import { START_UNIT_KEY } from "./lib";

/* eslint-disable @typescript-eslint/no-explicit-any */

type TargetComponentType<C> = NextComponentType<C, any, any>;
import { PageContext, TargetComponentType } from "./types";

export function withStart(unit: Unit<PageContext>) {
return (component: TargetComponentType<AppContext> | TargetComponentType<NextPageContext>) => {
Expand All @@ -17,7 +13,7 @@ export function withStart(unit: Unit<PageContext>) {
component.getInitialProps = async (ctx: any) => {
let initialProps = {};

if (originalGetInitialProps) {
if (typeof originalGetInitialProps === "function") {
initialProps = await originalGetInitialProps(ctx);
}

Expand Down

0 comments on commit 8c2c985

Please sign in to comment.