Skip to content

Commit

Permalink
chore: mod doc
Browse files Browse the repository at this point in the history
  • Loading branch information
fantasticsoul committed Jan 20, 2024
2 parents 75103a9 + 11b5159 commit e5ff591
Show file tree
Hide file tree
Showing 16 changed files with 245 additions and 40 deletions.
13 changes: 13 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# These are supported funding model platforms

github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: ['https://github.com/heluxjs/helux/issues/141', 'https://tnfe.gtimg.com/image/5a2u6arzpo_1705217036205.png']
49 changes: 49 additions & 0 deletions docs/docs/playground/demos/Playground/Tools.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
*
* 工具栏组件,
*
*
*
*/
import React, { useCallback } from "react";
import { codeContext, setCodeContext } from "./codeContext";
import { IconButton } from "./icons/IconButton";
import localforage from 'localforage';


export const Tools: React.FC = () => {

const saveCode = useCallback(() => {
localforage.setItem(`helux_code_${codeContext.key}`, codeContext.code, (err) => {
if (err) {
console.error(err)
} else {
console.info('code is saved')
}
})
}, [])

const resetCode = useCallback(() => {
localforage.removeItem(`helux_code_${codeContext.key}`, (err) => {
if (!err) {
setCodeContext(draft => { draft.code = '' })
}
})
}, [])

return <div style={{
position: "absolute",
display: "flex",
flexDirection: "column",
padding: "8px",
boxSizing: "border-box",
backgroundColor: "transparent",
left: "50%",
top: "36px",
width: "60px",
right: "10px",
}}>
<IconButton name="save" title="保存代码" onClick={() => saveCode()} />
<IconButton name="reset" title="恢复代码" onClick={() => resetCode()} />
</div>
}
6 changes: 5 additions & 1 deletion docs/docs/playground/demos/Playground/TopBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,21 @@ function renderItems(name: string, subName: string) {
));
}



export default React.memo(({ onClick, name, subName }: any) => {

const handleClick = e => {
const subName = e.target.dataset.name;
if (subName) {
onClick?.(subName);
}
};


return (
<div className="topBar" onClick={handleClick}>
{renderItems(name, subName)}
<span className='samples'>{renderItems(name, subName)}</span>
</div>
);
});
12 changes: 12 additions & 0 deletions docs/docs/playground/demos/Playground/codeContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { share } from "helux";

const [codeContext,setCodeContext,codeCtx] = share<{
key:string,
code:string
}>({key:"",code:"",})

export {
codeContext,
setCodeContext,
codeCtx
}
22 changes: 22 additions & 0 deletions docs/docs/playground/demos/Playground/icons/IconButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ReactNode,ButtonHTMLAttributes } from "react"
import { ResetIcon } from "./Reset"
import { SaveIcon } from "./Save"

export interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
name:"save" | 'reset'
}

const icons:Record<string,ReactNode> = {
save:<SaveIcon/>,
reset:<ResetIcon/>
}
export const IconButton:React.FC<IconButtonProps> = (props)=>{
return <button style={{
margin:"4px",
width:"32px",
height:"32px",
padding:"8px",
cursor:"pointer",
borderRadius:"24px"
}} {...props} type="button">{icons[props.name]}</button>
}
7 changes: 7 additions & 0 deletions docs/docs/playground/demos/Playground/icons/Reset.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { SVGProps } from "react";

export function ResetIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...props}><path fill="none" stroke="currentColor" strokeWidth="2" d="M20 8c-1.403-2.96-4.463-5-8-5a9 9 0 1 0 0 18a9 9 0 0 0 9-9m0-9v6h-6"></path></svg>
)
}
7 changes: 7 additions & 0 deletions docs/docs/playground/demos/Playground/icons/Save.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { SVGProps } from "react";

export function SaveIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...props}><path fill="currentColor" d="M23.681 6.158L17.843.32a1.093 1.093 0 0 0-.771-.32H1.092C.489 0 .001.489.001 1.091v21.817c0 .603.489 1.091 1.091 1.091h21.817c.603 0 1.091-.489 1.091-1.091V6.928c0-.301-.122-.574-.32-.771zM6.549 2.182h6.546v5.819H6.546zm0 19.635v-5.818h10.905v5.818zm15.273 0h-2.185v-6.908c0-.603-.489-1.091-1.091-1.091H5.455c-.603 0-1.091.489-1.091 1.091v6.909H2.182V2.181h2.182V9.09c0 .603.489 1.091 1.091 1.091h8.728c.603 0 1.091-.489 1.091-1.091V2.181h1.344l5.199 5.199z"></path></svg>
)
}
8 changes: 8 additions & 0 deletions docs/docs/playground/demos/Playground/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,16 @@
z-index: 200;
border: 1px solid #443782;
box-sizing: border-box;
position: relative;
display: flex;
}

.playground-wrap .topBar>.samples {
display: flex;
flex-grow: 1;
}


.playground-wrap .topBarItem {
display: inline-block;
height: 22px;
Expand Down
75 changes: 59 additions & 16 deletions docs/docs/playground/demos/Playground/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import React from 'react'
import React, { useCallback, useEffect } from 'react'
import { LiveProvider, LiveEditor, LiveError, LivePreview } from "react-live";
import qs from "qs";
import * as prism from 'prism-react-renderer';
import * as helux from 'helux';
import { useWatch } from 'helux';

import ApiMenus from './ApiMenus';
import TopBar from './TopBar';
import Console from './Console';
import * as codes from './codes';
import './index.less';
import { Tools } from './Tools';
import { setCodeContext, codeContext } from './codeContext';
import localforage from 'localforage';

function getCode(name: string, subName: string) {
function getCode(name: any, subName: any) {
const codeDict: any = codes;
return codeDict[name]?.[subName] || '';
}
Expand All @@ -20,32 +25,70 @@ const subNames: Record<string, string> = {
derive: 'primitive',
modular: 'defineActions',
};
const cachedSubNames: Record<string, string> = {};
const cachedSubNames: any = {};
const obj = qs.parse(window.location.search, { ignoreQueryPrefix: true });
const name = obj.n || 'atom';
const subName = obj.s || 'primitive';
const code = getCode(name, subName);

const name: string = (obj.n || 'atom') as unknown as string;
const subName: string = (obj.s || 'primitive') as unknown as string;
const initCode = getCode(name, subName);
setCodeContext(draft => {
draft.key = `${name}_${subName}`
})
function loadCode(name: any, subName: any, setCode: any) {
localforage.getItem(`helux_code_${name}_${subName}`, (err: any, value: any) => {
if (!err && typeof (value) === 'string' && value.trim().length > 0) {
setCode(value);
} else {
setCode(getCode(name, subName));
}
})
}
export default () => {
const [info, setInfo] = React.useState({ name, subName, code });
const changeCode = (name: string) => {
const [info, setInfo] = React.useState({ name, subName });
const [code, setCode] = React.useState(initCode);

useEffect(() => {
loadCode(name, subName, setCode)
}, [])

useWatch(() => {
const curCode = codeContext.code
if (curCode.trim().length === 0) {
loadCode(name, subName, setCode)
}
}, () => [codeContext.code])



const changeCode = useCallback((name: string) => {
const subName = cachedSubNames[name] || subNames[name] || 'primitive';
setInfo({ name, subName, code: getCode(name, subName) });
};
const changeSubName = (subName: string) => {
setCodeContext(draft => { draft.key = `${name}_${subName}` })
setInfo({ name, subName })
loadCode(name, subName, setCode)
}, [info.name, info.subName])

const changeSubName = useCallback((subName: string) => {
const { name } = info;
cachedSubNames[name] = subName;
setInfo({ name, subName, code: getCode(name, subName) });
};
setCodeContext(draft => {
draft.key = `${name}_${subName}`
})

setInfo({ name, subName })
loadCode(name, subName, setCode)
}, [info.name, info.subName])




return (
<LiveProvider noInline={true} code={info.code} scope={scope} theme={prism.themes.vsDark}>
<LiveProvider noInline={true} code={code} scope={scope} theme={prism.themes.vsDark}>
<div className="playground-wrap">
<div style={{ display: "flex", height: '100%', padding: '12px 100px' }}>
<ApiMenus onClick={changeCode} name={info.name} />
<div style={{ flex: "1 1 0px", height: '100%' }}>
<TopBar onClick={changeSubName} name={info.name} subName={info.subName} />
<LiveEditor style={{ height: '100%' }} />
<LiveEditor style={{ flexGrow: 1 }} onChange={value => { setCodeContext(draft => { draft.code = value }) }} />
<Tools />
</div>
<div style={{ flex: "1 1 0px", height: 'calc(100vh - 138px)' }}>
{/* 空占位一个条 */}
Expand Down
10 changes: 7 additions & 3 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,15 @@
},
"dependencies": {
"@ant-design/icons-svg": "^4.3.1",
"@helux/demo-utils": "0.0.3",
"@helux/demo-utils": "latest",
"@helux/utils": "latest",
"@makotot/ghostui": "^2.0.0",
"animated-scroll-to": "^2.3.0",
"classnames": "^2.5.0",
"console-feed": "^3.5.0",
"helux": "4.2.1",
"helux": "latest",
"helux-docs": "link:",
"localforage": "^1.10.0",
"lodash": "^4.17.21",
"lodash.throttle": "^4.1.1",
"prism-react-renderer": "^2.3.1",
Expand All @@ -66,6 +69,7 @@
"devDependencies": {
"@commitlint/cli": "^17.1.2",
"@commitlint/config-conventional": "^17.1.0",
"@types/qs": "^6.9.11",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@umijs/lint": "^4.0.0",
Expand All @@ -89,4 +93,4 @@
"access": "public"
},
"authors": []
}
}
16 changes: 8 additions & 8 deletions packages/helux-core/src/factory/createMutate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ const toMutateRet = (ret: ActionReturn) => [ret.snap, ret.err] as [any, Error |
/**
* 查找到配置到 mutate 函数并执行
*/
function runMutateFnItem<T = SharedState>(options: { target: T; desc?: string; forTask?: boolean; throwErr?: boolean }) {
const { target, desc: inputDesc = '', forTask = false, throwErr } = options;
function runMutateFnItem<T = SharedState>(options: { target: T; desc?: string; forTask?: boolean; throwErr?: boolean; extraArgs?: any }) {
const { target, desc: inputDesc = '', forTask = false, throwErr, extraArgs } = options;
const { mutateFnDict, snap } = getInternal(target);
const desc = inputDesc || SINGLE_MUTATE; // 未传递任何描述,尝试调用可能存在的单函数

Expand All @@ -40,7 +40,7 @@ function runMutateFnItem<T = SharedState>(options: { target: T; desc?: string; f

// throwErr 谨慎处理,只严格接受布尔值
const throwErrVar = ensureBool(throwErr, false);
const baseOpts = { sn: 0, fnItem: item, from: FROM.MUTATE, throwErr: throwErrVar };
const baseOpts = { sn: 0, fnItem: item, from: FROM.MUTATE, throwErr: throwErrVar, extraArgs };
// 调用 desc 对应的函数
if (forTask) {
return callAsyncMutateFnLogic(target, baseOpts);
Expand Down Expand Up @@ -130,29 +130,29 @@ function configureMutateDict(options: IConfigureMutateDictOpt): any {
*/
function prepareParms<T extends SharedState>(target: T, options: ILogicOptions) {
const { label, descOrOptions, forTask = false } = options;
const { desc, strict, throwErr } = parseCreateMutateOpt(descOrOptions);
const { desc, strict, throwErr, extraArgs } = parseCreateMutateOpt(descOrOptions);
if (!desc) {
return { ok: false, desc, forTask, throwErr, err: new Error('miss desc') };
}
const internal = checkShared(target, { label, strict });
if (!internal) {
return { ok: false, desc, forTask, throwErr, err: new Error('not a valid atom or shared result') };
return { ok: false, desc, forTask, throwErr, extraArgs, err: new Error('not a valid atom or shared result') };
}
return { ok: true, desc, forTask, throwErr, err: null };
return { ok: true, desc, forTask, throwErr, extraArgs, err: null };
}

/**
* 执行匹配 desc 的 mutate 函数
*/
export function runMutateLogic<T extends SharedState>(target: T, options: ILogicOptions): [T, Error | null] | Promise<[T, Error | null]> {
const { ok, desc, forTask, err, throwErr } = prepareParms(target, options);
const { ok, desc, forTask, err, throwErr, extraArgs } = prepareParms(target, options);
if (!ok) {
if (throwErr) {
throw err;
}
return forTask ? Promise.resolve([target, err]) : [target, err];
}
const result = runMutateFnItem({ target, desc, forTask, throwErr });
const result = runMutateFnItem({ target, desc, forTask, throwErr, extraArgs });
return forTask ? Promise.resolve(result).then(toMutateRet) : toMutateRet(result as ActionReturn);
}

Expand Down
Loading

0 comments on commit e5ff591

Please sign in to comment.