From 6cb0626f055b45a2984e0610691012b75fed8a42 Mon Sep 17 00:00:00 2001 From: hypercross Date: Wed, 22 Apr 2026 01:13:39 +0800 Subject: [PATCH] refactor: update produce signature to return undefined Change the return type of `produce` and `produceAsync` from `void` to `undefined` in `MutableSignal` and `IGameContext` to more accurately reflect that the mutation functions should not return a value. --- src/core/game.ts | 8 ++++---- .../slay-the-spire-like/system/combat/triggers.ts | 6 +++--- src/utils/mutable-signal.ts | 13 ++++++++----- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/core/game.ts b/src/core/game.ts index 50c396e..422d1f5 100644 --- a/src/core/game.ts +++ b/src/core/game.ts @@ -15,8 +15,8 @@ import { Mulberry32RNG, ReadonlyRNG, RNG } from "@/utils/rng"; export interface IGameContext = {}> { get value(): TState; get rng(): ReadonlyRNG; - produce(fn: (draft: TState) => void): void; - produceAsync(fn: (draft: TState) => void): Promise; + produce(fn: (draft: TState) => undefined): void; + produceAsync(fn: (draft: TState) => undefined): Promise; run(input: string): Promise>; runParsed(command: Command): Promise>; prompt: ( @@ -51,10 +51,10 @@ export function createGameContext = {}>( get rng() { return this._rng; }, - produce(fn) { + produce(fn: (draft: TState) => undefined) { return state.produce(fn); }, - produceAsync(fn) { + produceAsync(fn: (draft: TState) => undefined) { return state.produceAsync(fn); }, run(input: string) { diff --git a/src/samples/slay-the-spire-like/system/combat/triggers.ts b/src/samples/slay-the-spire-like/system/combat/triggers.ts index 9bc22ec..310cfe6 100644 --- a/src/samples/slay-the-spire-like/system/combat/triggers.ts +++ b/src/samples/slay-the-spire-like/system/combat/triggers.ts @@ -65,9 +65,9 @@ export function createTriggers(run: IRunContext) { for (const cardId of Object.values(regions.hand.childIds)) { await triggers.onCardDiscarded.execute(ctx.game, { cardId }); } - await ctx.game.produceAsync( - (draft) => (draft.player.energy = draft.player.maxEnergy), - ); + await ctx.game.produceAsync((draft) => { + draft.player.energy = draft.player.maxEnergy; + }); await triggers.onDraw.execute(ctx.game, { count: 5 }); }), onShuffle: createTrigger("onShuffle", async (ctx) => { diff --git a/src/utils/mutable-signal.ts b/src/utils/mutable-signal.ts index aefe76c..0017541 100644 --- a/src/utils/mutable-signal.ts +++ b/src/utils/mutable-signal.ts @@ -1,5 +1,5 @@ -import {Signal, SignalOptions} from '@preact/signals-core'; -import {create} from 'mutative'; +import { Signal, SignalOptions } from "@preact/signals-core"; +import { create } from "mutative"; export class MutableSignal extends Signal { private _interruptions: Promise[] = []; @@ -7,7 +7,7 @@ export class MutableSignal extends Signal { public constructor(t?: T, options?: SignalOptions) { super(t, options); } - produce(fn: (draft: T) => void) { + produce(fn: (draft: T) => undefined) { this.value = create(this.value, fn); } @@ -30,13 +30,16 @@ export class MutableSignal extends Signal { * 异步版本的 produce。会先等待所有通过 `addInterruption` 添加的 Promise 完成, * 然后再更新状态。适用于需要在状态更新前播放动画的场景。 */ - async produceAsync(fn: (draft: T) => void): Promise { + async produceAsync(fn: (draft: T) => undefined): Promise { await Promise.allSettled(this._interruptions); this._interruptions = []; this.produce(fn); } } -export function mutableSignal(initial?: T, options?: SignalOptions): MutableSignal { +export function mutableSignal( + initial?: T, + options?: SignalOptions, +): MutableSignal { return new MutableSignal(initial, options); }