Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .changeset/neat-bees-know.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@unisonjs/core': patch
---

Handle fast refresh for react hooks
6 changes: 3 additions & 3 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
"packageManager": "pnpm@8.15.3",
"type": "module",
"scripts": {
"build": "pnpm build-vue && pnpm build-js && pnpm build-types",
"build-js": "rimraf dist && rollup -c rollup.config.js",
"build-types": "tsc --noCheck && pnpm dlx tsc-alias",
"build": "rimraf dist && pnpm build-vue && pnpm build-js && pnpm build-types",
"build-js": "rimraf dist/*.js && rollup -c rollup.config.js",
"build-types": "rimraf dist/types && tsc --noCheck && pnpm dlx tsc-alias",
"build-vue": "pnpm build-vue-js && pnpm build-rm-vue-aliases",
"build-vue-js": "(rimraf vue/temp && cd vue && pnpm tsc --noCheck) || exit 0;",
"build-rm-vue-aliases": "(pnpm dlx tsc-alias -p vue/tsconfig.json) || exit 0;",
Expand Down
12 changes: 8 additions & 4 deletions packages/core/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export type Event = {

type OnFlushCallback = (event: Partial<Event>) => void;

class OnBeforeMount extends React.Component {
class OnBeforeMount extends React.Component<{ hooks: Function[] }> {
componentWillUnmount(): void {
for (const hook of this.props.hooks) {
hook();
Expand All @@ -74,8 +74,8 @@ class Context {
#parent: ComponentInternalInstance | null;
#renderTrigger: () => void = __DEV__
? () => {
warn("Can't trigger a new rendering, the state is not setup properly");
}
warn("Can't trigger a new rendering, the state is not setup properly");
}
: NOOP;
#isRunning = false;
#propsKeys: string[] = [];
Expand Down Expand Up @@ -150,7 +150,7 @@ class Context {
});
this.#renderEffect.scheduler = () => {
this.triggerRendering();
this.#renderJob = queueJob(() => {});
this.#renderJob = queueJob(() => { });
this.#shouldGenerateTemplate = true;
};
}
Expand Down Expand Up @@ -180,6 +180,10 @@ class Context {
return this.#plugins?.get(key) as InstanceType<T>;
}

get plugins() {
return this.#plugins;
}

set children(children: () => React.ReactNode) {
this.#children = children;
}
Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/management.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,12 @@ export function $unison<T extends Record<string, any>>(fn: SetupComponent<T>, na
instance.setupState();
const trackedProps = instance.trackProps({ ...props, ref });

if (instance.isFastRefresh() && instance.plugins) {
for (const plugin of instance.plugins.values()) plugin.onInstanceFastRefresh?.(instance);
}

if (!instance.isExecuted() || instance.isFastRefresh()) {
instance.children = fn(trackedProps);
instance.children = fn(trackedProps as any);
instance.invalidateChildren();
}

Expand Down
14 changes: 12 additions & 2 deletions packages/core/src/plugins/hook-manager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export class HookManager implements UnisonPlugin {
this.#hookEffect.scheduler = () => instance.triggerRendering();

instance.addEventListener(Events.BEFORE_FLUSHING_PRE_EFFECT, ({ job }) => {
if (!instance.isExecuted()) return;
if (!instance.isExecuted() || instance.isFastRefresh()) return;
if (job) {
const position = job.position || 0;
while (this.#i < position) {
Expand All @@ -73,7 +73,7 @@ export class HookManager implements UnisonPlugin {
});

instance.addEventListener(Events.AFTER_FLUSHING_ALL_PRE_EFFECT, () => {
if (!instance.isExecuted()) return;
if (!instance.isExecuted() || instance.isFastRefresh()) return;
while (this.#i < this.#hooks.length && !instance.hasPendingPreEffects()) {
this.processHook(this.#hooks[this.#i]);
this.#i++;
Expand All @@ -86,6 +86,16 @@ export class HookManager implements UnisonPlugin {
this.#i = 0;
});
}
reset() {
this.#hookKeys.length = 0;
this.#hookSignals.length = 0;
this.#hookValues.length = 0;
this.#hooks.length = 0;
this.#hookEffect = new ReactiveEffect(NOOP);
}
onInstanceFastRefresh(instance: ComponentInternalInstance): void {
this.reset();
}
onInstanceDisposed(): void {}

getValueAt(index: number) {
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/plugins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ export type UnisonPluginClass = ClassType<UnisonPlugin>;

export interface UnisonPlugin {
onInstanceCreated(instance: ComponentInternalInstance): void
onInstanceFastRefresh(instance: ComponentInternalInstance): void
onInstanceDisposed(instance: ComponentInternalInstance): void
}
1 change: 0 additions & 1 deletion packages/core/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"emitDeclarationOnly": true,
"moduleResolution": "bundler",
"allowJs": true,
"noCheck": true,
"strict": true,
"noUnusedLocals": true,
"experimentalDecorators": true,
Expand Down
Loading