Skip to content

Commit fd90648

Browse files
committed
update
1 parent 360464f commit fd90648

8 files changed

Lines changed: 89 additions & 32 deletions

File tree

docs/zh/store/guide/store/config.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -625,12 +625,12 @@ const netStore = new AutoStore(
625625
dhcp: true,
626626
ip: configurable("192.168.1.1", {
627627
label: "IP地址",
628-
enable: (scope: any) => {
629-
// ❗ scope===AutoStoreConfigManager.state
630-
// ❗ 而dhcp并没有声明为可配置项
631-
// ❗ 因此AutoStoreConfigManager.state不存在network.dhcp
632-
// ❗ enable是在AutoStoreConfigManager
633-
// ❗ dhcp是在netStore,两者并不在同一个Store中
628+
enable: (scope: any, { refStore }) => {
629+
//❗ scope===AutoStoreConfigManager.state
630+
//❗ 而dhcp并没有声明为可配置项
631+
//❗ 因此AutoStoreConfigManager.state不存在network.dhcp
632+
//❗ enable是在AutoStoreConfigManager
633+
//❗ dhcp是在netStore,两者并不在同一个Store中
634634
return scope["network.dhcp"].value; // [!code ++] ❌无效
635635
},
636636
}),

packages/core/__tests__/ip.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,19 @@ configManager.watch(({ path, value }) => {
1414
});
1515
const netStore = new AutoStore(
1616
{
17-
dhcp: configurable(true, {
18-
label: "自动获取IP地址",
19-
}),
17+
dhcp: true,
2018
ip: configurable("192.168.1.1", {
2119
label: "IP地址",
22-
enable: (scope: any) => {
20+
enable: (scope: any, { ref }) => {
2321
return scope["network.dhcp"].value;
2422
},
2523
}),
2624
},
2725
{ configManager, id: "network" },
2826
);
2927
netStore.state.dhcp = true;
30-
console.log(configManager.state["network.dhcp"].value);
28+
// console.log(configManager.state["network.dhcp"].value);
3129
console.log(configManager.state["network.ip"].enable);
3230
netStore.state.dhcp = false;
33-
console.log(configManager.state["network.dhcp"].value);
31+
// console.log(configManager.state["network.dhcp"].value);
3432
console.log(configManager.state["network.ip"].enable);

packages/core/src/computed/async.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ export class AsyncComputedObject<Value = any, Scope = any> extends ComputedObjec
325325
operate: options.operate,
326326
first: options.first,
327327
abortSignal: abortController.signal,
328+
ref: () => undefined as any,
328329
};
329330

330331
const ctx: GetterRunContext = {

packages/core/src/computed/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import type {
2525
import type { StateOperate } from "../store/types";
2626
import type { ComputedObject } from "./computedObject";
2727
import type { Dict } from "../types";
28+
import { RefState } from "../store/refState";
2829

2930
/**
3031
* 同步计算属性配置参数
@@ -95,6 +96,7 @@ export interface AsyncComputedGetterArgs {
9596
* 是否是第一次运行
9697
*/
9798
first?: boolean;
99+
ref?: <Value = any>(path: string | string[]) => Value;
98100
}
99101

100102
export type AsyncComputedGetter<Value, Scope = any> = (

packages/core/src/observer/observer.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import type { StateOperate, StoreEvents, UpdateOptions } from "../store/types";
1717
import type { Watcher, WatchListenerOptions } from "../watch/types";
1818
import { calcDependPaths } from "../utils/calcDependPaths";
1919
import { isFunction } from "flex-tools/typecheck/isFunction";
20+
import { createRefState, RefState } from "../store/refState";
2021

2122
export class ObserverObject<
2223
Value = any,
@@ -36,6 +37,7 @@ export class ObserverObject<
3637
private _error?: Error; // 记录最后一次运行时的错误
3738
store: AutoStore<any>;
3839
_shadowStore!: AutoStore<any>;
40+
_refState?: RefState;
3941
/**
4042
* 构造函数。
4143
*
@@ -172,6 +174,16 @@ export class ObserverObject<
172174
}
173175
this.onInitial();
174176
}
177+
private _createRefState() {
178+
// @ts-expect-error
179+
const _getRefStore = this.descriptor.getter._getRefStore;
180+
if (isFunction(_getRefStore)) {
181+
const storeRef = _getRefStore() as WeakRef<AutoStore<any>>;
182+
if (storeRef) {
183+
this._refState = createRefState(storeRef, this as ObserverObject);
184+
}
185+
}
186+
}
175187
/**
176188
* 供子类继承进行初始化
177189
*/

packages/core/src/schema/manager.ts

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { PATH_DELIMITER, GLOBAL_CONFIG_MANAGER } from "../consts";
22
import { AutoStore } from "../store/store";
3-
import { isSchemaBuilder, markRaw, setVal, withSchema } from "../utils";
3+
import { isRaw, isSchemaBuilder, markRaw, setVal, withSchema } from "../utils";
44
import { getVal } from "../utils/getVal";
55
import type { SchemaDescriptor, SchemaDescriptorBuilder, AutoStoreConfigures } from "./types";
66
import { isFunction } from "../utils/isFunction";
@@ -230,6 +230,33 @@ export class ConfigManager extends AutoStore<
230230
if ((descriptor.schema as any).onInvalid === undefined) {
231231
(descriptor.schema as any).onInvalid = "throw";
232232
}
233+
// 安装校验器
234+
this._installValidator(strPath, descriptor, store);
235+
// 由于该配置项可能已先load还未注册,因此需要覆盖现有的值
236+
const loadedValue = this.peep((state) =>
237+
getVal(state, [configKey.join(PATH_DELIMITER), "value"]),
238+
);
239+
// 用于为schema中的observerObject提供refStore,以便能访问
240+
this._handleRefState(descriptor.schema, store);
241+
// 动态添加
242+
this.state[configKey.join(PATH_DELIMITER)] = descriptor.schema;
243+
if (loadedValue !== undefined) {
244+
descriptor.schema.value = loadedValue;
245+
}
246+
// 创建代理用于从原始的Store值读写状态值
247+
this._createValueProxy(descriptor, store, pathKey);
248+
249+
// 返回初始值,避免读取代理导致循环依赖
250+
return loadedValue || initialValue;
251+
}
252+
private _handleRefState(schema: object, store: AutoStore<any>) {
253+
Object.values(schema).forEach((v) => {
254+
if (isFunction(v) && !isRaw(v)) {
255+
v._getRefStore = () => new WeakRef(store);
256+
}
257+
});
258+
}
259+
private _installValidator(path: string, descriptor: SchemaDescriptor, store: AutoStore<any>) {
233260
if (isFunction(descriptor.schema.validate)) {
234261
// 将getErrorMessage 方法和validationBehavior添加到验证函数上,用于在isValidPass中使用
235262
// @ts-expect-error
@@ -252,34 +279,19 @@ export class ConfigManager extends AutoStore<
252279
if (!store.options.validators) {
253280
store.options.validators = {};
254281
}
255-
store.options.validators[strPath] = descriptor.schema.validate;
282+
store.options.validators[path] = descriptor.schema.validate;
256283
} else {
257284
if (store.options.validators) {
258-
delete store.options.validators[strPath];
285+
delete store.options.validators[path];
259286
}
260287
}
261-
// 由于该配置项可能已先load还未注册,因此需要覆盖现有的值
262-
const loadedValue = this.peep((state) =>
263-
getVal(state, [configKey.join(PATH_DELIMITER), "value"]),
264-
);
265-
266-
// 动态添加
267-
this.state[configKey.join(PATH_DELIMITER)] = descriptor.schema;
268-
if (loadedValue !== undefined) {
269-
descriptor.schema.value = loadedValue;
270-
}
271-
272-
// 创建代理用于从原始的Store值读写状态值
273-
this._createValueProxy(descriptor, store, pathKey);
274-
275-
// 返回初始值,避免读取代理导致循环依赖
276-
return loadedValue || initialValue;
277288
}
278289
private _createValueProxy(
279290
finalDescriptor: SchemaDescriptor,
280291
store: AutoStore<any>,
281292
path: string[],
282293
) {
294+
// oxlint-disable-next-line typescript/no-this-alias
283295
const self = this;
284296

285297
// 由于ConfigManager是全局对象,而Store可能是动态,可能会被销毁,因此应采用弱引用
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { ObserverObject } from "../observer";
2+
import { AutoStore } from "./store";
3+
import type { Dict } from "../types";
4+
import { getVal } from "../utils/getVal";
5+
import { Watcher } from "../watch/types";
6+
7+
export type RefState = {
8+
off: () => void;
9+
ref: <Value = any>(path: string | string[]) => Value | undefined;
10+
};
11+
12+
export function createRefState(
13+
storeRef: WeakRef<AutoStore<any>>,
14+
observerObj: ObserverObject,
15+
): RefState {
16+
let watcher: Watcher | null = null;
17+
return {
18+
ref: <Value = any>(path: string | string[], args?: Record<string, any>) => {
19+
const store = storeRef.deref();
20+
if (store) {
21+
if (!watcher) {
22+
watcher = store.watch(path, () => {
23+
observerObj.run(args);
24+
});
25+
}
26+
return getVal(store.state, path) as Value;
27+
}
28+
},
29+
off: () => {
30+
watcher?.off();
31+
},
32+
};
33+
}

packages/core/src/types/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ export type PickComputedResult<T> =
7777
如:ComputedState<{count:async ()=>1}> => {count:number}
7878
7979
*/
80-
8180
export type ComputedState<T> = T extends unknown[]
8281
? ComputedState<T[number]>[]
8382
: T extends RawObject<T>

0 commit comments

Comments
 (0)