Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
2208df6
build(docs): optimize tool
Aug 9, 2025
eaa4a3d
chore: change to latest
Aug 9, 2025
00f7d6c
chore: del react-toastify
Aug 9, 2025
f30eef3
chore: bump pnpm in workflows/website.yml
Aug 11, 2025
0decefa
docs(changeset): optimize mid
Aug 26, 2025
381023a
RELEASING: Releasing 8 package(s)
Aug 26, 2025
45f3912
docs(changeset): support syncer string
Oct 24, 2025
f44822a
RELEASING: Releasing 8 package(s)
Oct 24, 2025
1f6eb26
build(5.5.2): support pass string to syncer
Oct 24, 2025
7be2611
docs(changeset): optimize syncer
Oct 24, 2025
bc4bc6b
RELEASING: Releasing 8 package(s)
Oct 24, 2025
6b8cd11
feat: optimize syncer
Oct 24, 2025
8aa2422
docs(changeset): export useStable from top api
Dec 11, 2025
657b86c
RELEASING: Releasing 8 package(s)
Dec 11, 2025
4347ce9
docs(changeset): bump
Dec 11, 2025
57ecd7f
RELEASING: Releasing 8 package(s)
Dec 11, 2025
79235a0
docs(changeset): add enhanceStore
Jan 9, 2026
e438b08
RELEASING: Releasing 8 package(s)
Jan 9, 2026
5cd1b7f
feat: add enhanceStore
Jan 9, 2026
dab4a45
feat: add enhanceStore
Jan 9, 2026
110a214
docs(changeset): optimize enhanceStore type
Mar 26, 2026
a847e20
RELEASING: Releasing 8 package(s)
Mar 26, 2026
c84b571
feat: optimize enhanceStore type
Mar 26, 2026
43eb7b2
docs(changeset): add ns
Mar 26, 2026
1f2b6ef
RELEASING: Releasing 8 package(s)
Mar 26, 2026
701bc35
docs(changeset): bump limu
Apr 1, 2026
c9a0866
RELEASING: Releasing 8 package(s)
Apr 1, 2026
0916e9b
docs(changeset): bump limu
Apr 1, 2026
900223e
RELEASING: Releasing 8 package(s)
Apr 1, 2026
e273cae
docs(changeset): expose useEffect
Jun 16, 2026
23e4c71
RELEASING: Releasing 8 package(s)
Jun 16, 2026
191a532
feat: expose useEffect useLayoutEffect
Jun 16, 2026
4641f5d
feat: fix type file typo
Jul 20, 2026
ca5b930
docs(changeset): fix type file
Jul 20, 2026
fffd683
RELEASING: Releasing 8 package(s)
Jul 20, 2026
da7b140
feat: mod VER
Jul 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@
"changelog": "@changesets/cli/changelog",
"commit": true,
"fixed": [
["helux", "@helux/core", "@helux/openinula", "@helux/hooks", "@helux/hooks-impl", "@helux/types", "@helux/utils"]
[
"helux",
"@helux/core",
"@helux/openinula",
"@helux/hooks",
"@helux/hooks-impl",
"@helux/types",
"@helux/utils"
]
],
"linked": [],
"access": "restricted",
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/website.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
# 如果配置 themeConfig.lastUpdated 为 false,则不需要添加该参数以加快检出速度
fetch-depth: 0
- name: Install pnpm
run: npm install -g pnpm@7.9.5
run: npm install -g pnpm@10.5.2
- name: Install dependencies
run: pnpm install --no-frozen-lockfile
- name: Build helux libs
Expand Down
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
strict-peer-dependencies=false
auto-install-peers=true
5 changes: 4 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@ fixtures
*.yaml
*.less
.turbo
.changeset
docs
doc/src/components
./.changeset/config.json
packages/f-guard/__tests__
packages/helux-core/src/helpers/state.ts
5 changes: 5 additions & 0 deletions PUB.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,9 @@

3. 发布时执行 `pnpm changeset publish`

```bash
# 需要补充 otp 值
pnpm changeset publish --otp=xxxxxx
```

发布配置见 `.changeset/config.json` 文件
2 changes: 1 addition & 1 deletion docs/docs/api/utils/mark-raw.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { markRaw, atom } from 'helux';
const [ state, setState, ctx ] = atom({ a: { } });

setState(draft=>{
draft.a.k1 = markRaw(AComplexThridObject);
draft.a.k1 = markRaw(aComplexThirdObject);
});

function Demo(){
Expand Down
81 changes: 45 additions & 36 deletions docs/docs/playground/demos/Playground/Tools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,54 @@
*
*
*/
import React, { useCallback } from "react";
import { codeContext, setCodeContext } from "./codeContext";
import React from "react";
import { IconButton } from "./icons/IconButton";
import localforage from 'localforage';

const stControlWrap: React.CSSProperties = { width: '156px', transform: 'translateX(-105px)' };
const stWrap: React.CSSProperties = {
position: "absolute",
display: "flex",
flexDirection: "column",
padding: "8px",
boxSizing: "border-box",
backgroundColor: "transparent",
left: "50%",
top: "26px",
width: "60px",
transform: 'translateX(-15px)',
};

export const Tools: React.FC = () => {
export const Tools: React.FC<any> = (props) => {
const { mode, onControlClick, onRunClick, copyUrl, saveCode, resetCode, recoverCode } = props;
const liveBtnStyle = mode === 'live' ? { backgroundColor: 'lightskyblue' } : {};
const lagBtnStyle = mode === 'lag' ? { backgroundColor: 'lightskyblue' } : {};
const manualBtnStyle = mode === 'manual' ? { backgroundColor: 'lightskyblue' } : {};

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()} />
return <div style={stWrap}>
<div style={stControlWrap}>
<IconButton
name="实时"
title="预览区实时响应编辑器代码"
style={liveBtnStyle}
onClick={() => onControlClick('live')}
/>
<IconButton
name="延时"
title="预览区延时响应编辑器代码"
style={lagBtnStyle}
onClick={() => onControlClick('lag')}
/>
<IconButton
name="手动"
title="手动点击运行后,预览区才响应编辑器代码"
style={manualBtnStyle}
onClick={() => onControlClick('manual')}
/>
</div>
<IconButton name="重置" title="重置代码" onClick={resetCode} />
{(mode === 'manual' || mode === 'lag') && <IconButton name="保存" title="保存代码" onClick={() => saveCode()} />}
<IconButton name="恢复" title="恢复保存代码" onClick={recoverCode} />
{mode === 'manual' && <IconButton name="运行" title="运行代码" onClick={() => onRunClick?.()} />}
<IconButton name="copy" title="复制当前示例链接" onClick={() => copyUrl?.()} />
</div>
}
3 changes: 2 additions & 1 deletion docs/docs/playground/demos/Playground/codes/atom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ const change = () => {
// draft was already unboxed from { val: T } to T
draft.b.b1.b2 += 100;
})
console.log('dict.val.b.b1.b2 is ', dict.val.b.b1.b2);
console.log('proxy dict.val.b ', dict.val.b);
console.log('original dict.val.b ', limu.original(dict.val.b));
};

render(<button onClick={ change } > change { $(dict.val.b.b1.b2)}</button>);
Expand Down
37 changes: 22 additions & 15 deletions docs/docs/playground/demos/Playground/icons/IconButton.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
import { ReactNode,ButtonHTMLAttributes } from "react"
import { ReactNode, ButtonHTMLAttributes } from "react"
import { ResetIcon } from "./Reset"
import { SaveIcon } from "./Save"

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

const icons:Record<string,ReactNode> = {
save:<SaveIcon/>,
reset:<ResetIcon/>
const defaultStyle = {
width: "52px",
height: "28x",
cursor: "pointer",
borderRadius: "12px",
textAlign: 'center',
};

const icons: Record<string, ReactNode> = {
save: <SaveIcon />,
reset: <ResetIcon />,
run: 'Run',
copy: 'Copy',
}
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>
export const IconButton: React.FC<IconButtonProps> = (props) => {
const { name, style, ...rest } = props;
console.log('style', style);
const uiName = icons[name] || name;
const stBtn = Object.assign({}, defaultStyle, style || {});
return <button style={stBtn} {...rest} type="button">{uiName}</button>
}
95 changes: 86 additions & 9 deletions docs/docs/playground/demos/Playground/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import React, { useCallback, useEffect } from 'react'
import { LiveProvider, LiveEditor, LiveError, LivePreview } from "react-live";
import copyTo from 'copy-to-clipboard';
import qs from "qs";
import * as prism from 'prism-react-renderer';
import * as helux from 'helux';
import { useWatch } from 'helux';
import localforage from 'localforage';
// TODO toast 无效
// import { toast } from 'react-toastify';

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 { Tools } from './Tools';
import { setCodeContext, codeContext } from './codeContext';
import localforage from 'localforage';

function getCode(name: any, subName: any) {
const codeDict: any = codes;
Expand Down Expand Up @@ -44,9 +47,55 @@ function loadCode(name: any, subName: any, setCode: any) {
})
}

let timer: any;

function useLogic(name = 'atom', subName = 'primitive') {
const [info, setInfo] = React.useState({ name, subName });
const [code, setCode] = React.useState(initCode);
const [mode, setMode] = React.useState('live'); // live lag manual
const [compKey, setCompKey] = React.useState(Date.now());
const codeCacheRef = React.useRef(code);

const clickRun = () => {
setCode(codeCacheRef.current);
setCompKey(Date.now());
};
const onControlClick = (mode: string) => {
setMode(mode);
};
const copyUrl = () => {
const url = `${window.location.origin}?n=${info.name}&s=${info.subName}`;
copyTo(url);
console.log('复制当前示例分享链接成功', url);
};
const saveCode = () => {
localforage.setItem(`helux_code_${info.name}_${info.subName}`, codeCacheRef.current, (err) => {
if (err) {
return console.log(err);
}
console.log('保存成功');
});
};
const changeEditorCode = (value: string) => {
codeCacheRef.current = value;
setCode(value);
setCompKey(Date.now());
};
const recoverCode = () => {
localforage.getItem(`helux_code_${info.name}_${info.subName}`, (err, value: string | null) => {
if (err) {
return alert(err.message);
}
if (!value) {
return alert('无最近保存的代码可恢复');
}
changeEditorCode(value);
});
};
const resetCode = () => {
changeEditorCode(getCode(info.name, info.subName));
console.log('重置示例代码成功');
};

useEffect(() => {
loadCode(name, subName, setCode);
Expand Down Expand Up @@ -77,12 +126,28 @@ function useLogic(name = 'atom', subName = 'primitive') {
loadCode(name, subName, setCode);
}, [info.name, info.subName]);

return { info, code, changeCode, changeSubName };
const onEditorCodeChange = (value: string) => {
if (mode !== 'lag') {
// 是手动,仅保存代码
codeCacheRef.current = value;
return;
}
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
changeEditorCode(value);
}, 1000);
};

return {
info, code, changeCode, changeSubName, onControlClick, mode, compKey, clickRun,
onEditorCodeChange, copyUrl, saveCode, resetCode, recoverCode, changeEditorCode,
};
}

export function SimplePlayground() {
const { info, code, changeCode, changeSubName } = useLogic('quickStart', 'HelloHelux');

return (
<LiveProvider noInline={true} code={code} scope={scope} theme={prism.themes.vsDark}>
<div className="simple-playground-wrap">
Expand Down Expand Up @@ -110,9 +175,13 @@ export function SimplePlayground() {
}

export default () => {
const { info, code, changeCode, changeSubName } = useLogic(name, subName);
const {
info, code, changeCode, changeSubName, onControlClick, mode, clickRun, compKey,
onEditorCodeChange, copyUrl, saveCode, resetCode, recoverCode,
} = useLogic(name, subName);

return (
<LiveProvider noInline={true} code={code} scope={scope} theme={prism.themes.vsDark}>
<LiveProvider key={compKey} noInline={true} code={code} scope={scope} theme={prism.themes.vsDark}>
<div className="playground-wrap">
<div className="leftMenuWrap">
<ApiMenus onClick={changeCode} name={info.name} />
Expand All @@ -121,9 +190,17 @@ export default () => {
<TopBar onClick={changeSubName} name={info.name} subName={info.subName} />
<div style={{ display: "flex", height: '100%', padding: '0 2px' }}>
<div style={{ flex: "1 1 0px", height: '100%' }}>
{/* <LiveEditor style={{ flexGrow: 1 }} onChange={value => { setCodeContext(draft => { draft.code = value }) }} /> */}
<LiveEditor style={{ flexGrow: 1 }} />
{/* <Tools /> */}
{mode === 'live' && <LiveEditor style={{ flexGrow: 1 }} />}
{mode !== 'live' && <LiveEditor style={{ flexGrow: 1 }} onChange={onEditorCodeChange} />}
<Tools
onRunClick={clickRun}
onControlClick={onControlClick}
copyUrl={copyUrl}
mode={mode}
saveCode={saveCode}
resetCode={resetCode}
recoverCode={recoverCode}
/>
</div>
<div style={{ flex: "1 1 0px", height: 'calc(100vh - 118px)' }}>
<div style={{ height: '50%', padding: '12px', boxSizing: 'border-box', border: '1px solid #e8ae56' }}>
Expand Down
9 changes: 5 additions & 4 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"animated-scroll-to": "^2.3.0",
"classnames": "^2.5.0",
"console-feed": "^3.5.0",
"copy-to-clipboard": "^3.3.3",
"helux": "latest",
"localforage": "^1.10.0",
"lodash": "^4.17.21",
Expand All @@ -70,8 +71,8 @@
"@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",
"@types/react": "18.0.0",
"@types/react-dom": "18.0.0",
"@umijs/lint": "^4.0.0",
"dumi": "^2.2.16",
"eslint": "^8.23.0",
Expand All @@ -81,8 +82,8 @@
"prettier": "^2.7.1",
"prettier-plugin-organize-imports": "^3.0.0",
"prettier-plugin-packagejson": "^2.2.18",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react": "18.0.0",
"react-dom": "18.0.0",
"stylelint": "^14.9.1"
},
"peerDependencies": {
Expand Down
Loading
Loading