Skip to content
This repository has been archived by the owner on Nov 17, 2022. It is now read-only.

feat: store initialStates #435

Merged
merged 13 commits into from
Oct 17, 2022
3 changes: 2 additions & 1 deletion examples/with-store/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"devDependencies": {
"@ice/plugin-store": "workspace:*",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0"
"@types/react-dom": "^18.0.0",
"tslib": "^2.4.0"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为啥需要这个

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Copy link
Collaborator

@ClarkXia ClarkXia Aug 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

所以项目依赖中你会推荐把 tslib 也默认加进去吗

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

看 next 也会加 tslib

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好多地方都会用到, ts 优先的话我也建议脚手架默认加 tslib 在 devDep

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

或者也可以默认先不依赖 tslib,把可能遇到的错误以及解决方式(安装一下 tslib)放在 faq 中

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里不用增加复杂度了, 直接脚手架里依赖上吧 (开箱即用)

}
}
20 changes: 20 additions & 0 deletions examples/with-store/src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
import { defineAppConfig } from 'ice';
import { defineStoreConfig } from '@ice/plugin-store/esm/types';

export const store = defineStoreConfig(async (appData) => {
// fetch Data
return {
initialStates: {
...appData,
},
};
});

export const getAppData: GetAppData = () => {
return new Promise((resolve) => {
resolve({
user: {
name: 'icejs',
},
});
});
};

export default defineAppConfig({});
2 changes: 1 addition & 1 deletion examples/with-store/src/models/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { createModel } from 'ice';

export default createModel({
state: {
name: 'ICE 3',
name: '',
},
});
19 changes: 19 additions & 0 deletions packages/plugin-store/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# @ice/plugin-store

A plugin of state management base on Redux and React Redux used in framework `ICE`.

## Usage

```ts
import { defineConfig } from '@ice/app';
import store from '@ice/plugin-store';
export default defineConfig({
plugins: [
store(),
],
});
```

## Options

- disableResetPageState: 默认值是 `false`。开启后,切换页面再次进入原页面后不会重新初始化页面状态
14 changes: 13 additions & 1 deletion packages/plugin-store/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@
"types": "./esm/api.d.ts",
"import": "./esm/api.js",
"default": "./esm/api.js"
},
"./types": {
"types": "./esm/types.d.ts",
"import": "./esm/types.js",
"default": "./esm/types.js"
},
"./esm/types": {
"types": "./esm/types.d.ts",
"import": "./esm/types.js",
"default": "./esm/types.js"
}
},
"main": "./esm/index.js",
Expand All @@ -28,12 +38,14 @@
"!esm/**/*.map"
],
"dependencies": {
"@ice/store": "^2.0.1",
"@ice/store": "^2.0.3",
"fast-glob": "^3.2.11",
"micromatch": "^4.0.5"
},
"devDependencies": {
"@ice/types": "^1.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@types/micromatch": "^4.0.2",
Expand Down
3 changes: 3 additions & 0 deletions packages/plugin-store/src/_store.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/**
* This file which is imported by the runtime.tsx, is to avoid TS error.
*/
import type { IcestoreDispatch, IcestoreRootState } from '@ice/store';
import { createStore } from '@ice/store';

Expand Down
10 changes: 7 additions & 3 deletions packages/plugin-store/src/runtime.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import * as React from 'react';
import type { RuntimePlugin, AppProvider, RouteWrapper } from '@ice/types';
import { PAGE_STORE_INITIAL_STATES, PAGE_STORE_PROVIDER } from './constants.js';
import type { StoreConfig } from './types.js';
import appStore from '$store';

const runtime: RuntimePlugin = async ({ addWrapper, addProvider, useAppContext }) => {
const runtime: RuntimePlugin = async ({ appContext, addWrapper, addProvider, useAppContext }) => {
const { appExport, appData } = appContext;
const storeConfig: StoreConfig = (typeof appExport.store === 'function'
? (await appExport.store(appData)) : appExport.store) || {};
const { initialStates } = storeConfig;
if (appStore && Object.prototype.hasOwnProperty.call(appStore, 'Provider')) {
// Add app store Provider
const StoreProvider: AppProvider = ({ children }) => {
return (
// TODO: support initialStates: https://github.com/ice-lab/ice-next/issues/395#issuecomment-1210552931
<appStore.Provider>
<appStore.Provider initialStates={initialStates}>
{children}
</appStore.Provider>
);
Expand Down
13 changes: 13 additions & 0 deletions packages/plugin-store/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export interface StoreConfig {
initialStates: Record<string, any>;
}

type Store = ((data?: any) => Promise<StoreConfig>) | StoreConfig;

function defineStoreConfig(fn: Store) {
return fn;
}

export {
defineStoreConfig,
};
40 changes: 22 additions & 18 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tests/integration/with-store.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe(`build ${example}`, () => {
page = res.page;
browser = res.browser;
await page.waitForFunction('document.getElementsByTagName(\'button\').length > 0');
expect(await page.$$text('#username')).toStrictEqual(['name: ICE 3']);
expect(await page.$$text('#username')).toStrictEqual(['name: icejs']);
expect(await page.$$text('#count')).toStrictEqual(['0']);
}, 120000);

Expand Down