Skip to content

Commit ce5890d

Browse files
committed
feat: schema增加签名调用,可以省略初始化值
1 parent e851fe0 commit ce5890d

File tree

6 files changed

+185
-149
lines changed

6 files changed

+185
-149
lines changed

docs/public/autoform.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/public/autostore.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/zh/store/guide/store/schema.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,22 @@ store.on('validate', ({
199199

200200
```
201201
202+
### 动态创建
203+
204+
可以动态创建`schema`对象。
205+
206+
```ts
207+
import { s } from 'autostore';
208+
const store = new AutoStore({
209+
user: {
210+
name: 'voerkai18n'
211+
}
212+
})
213+
214+
store.schemas.add('user.name', schema({.....}))
215+
216+
```
217+
202218
### 访问数据
203219
204220
`store.schemas.getState()`用来提取出所以`schema`标注过的所有数据。
Lines changed: 150 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -1,157 +1,166 @@
1-
import { PATH_DELIMITER } from "../consts";
2-
import type { AutoStore } from "../store/store";
3-
import type { Dict } from "../types";
4-
import { isSchemaBuilder, markRaw, pathStartsWith, setVal } from "../utils";
5-
import { getVal } from "../utils/getVal";
6-
import { parseFunc } from "../utils/parseFunc";
1+
import { PATH_DELIMITER } from '../consts';
2+
import type { AutoStore } from '../store/store';
3+
import type { Dict } from '../types';
4+
import { isSchemaBuilder, markRaw, pathStartsWith, setVal } from '../utils';
5+
import { getVal } from '../utils/getVal';
6+
import { parseFunc } from '../utils/parseFunc';
77
import type {
8-
SchemaOptions,
9-
SchemaValidator,
10-
ComputedSchemaState,
11-
SchemaDescriptor,
12-
SchemaDescriptorBuilder,
13-
} from "./types";
8+
SchemaOptions,
9+
SchemaValidator,
10+
ComputedSchemaState,
11+
SchemaDescriptor,
12+
SchemaDescriptorBuilder,
13+
} from './types';
1414

1515
export class SchemaManager<
16-
State extends Dict,
17-
SchemaStore extends AutoStore<ComputedSchemaState<State>> = AutoStore<ComputedSchemaState<State>>,
16+
State extends Dict,
17+
SchemaStore extends AutoStore<ComputedSchemaState<State>> = AutoStore<
18+
ComputedSchemaState<State>
19+
>,
1820
> {
19-
errors: Dict<string> = {}; // {<路径名称>:"错误信息"}
20-
_subscribers: any[] = [];
21-
store!: SchemaStore;
22-
_descriptors: Record<string, SchemaDescriptor["options"]> = {};
23-
constructor(public shadow: AutoStore<any>) {}
21+
errors: Dict<string> = {}; // {<路径名称>:"错误信息"}
22+
_subscribers: any[] = [];
23+
store!: SchemaStore;
24+
_descriptors: Record<string, SchemaDescriptor['options']> = {};
25+
constructor(public shadow: AutoStore<any>) {}
2426

25-
get fields() {
26-
return this.store.state as Record<string, SchemaOptions>;
27-
}
28-
get size() {
29-
return Object.keys(this.fields).length;
30-
}
27+
get fields() {
28+
return this.store.state as Record<string, SchemaOptions>;
29+
}
30+
get size() {
31+
return Object.keys(this.fields).length;
32+
}
3133

32-
_getKey(path: any): string {
33-
return Array.isArray(path) ? path.join("_$_") : path.split(PATH_DELIMITER).join("_$_");
34-
}
35-
_getPath(path: string) {
36-
return path.split("_$_");
37-
}
34+
_getKey(path: any): string {
35+
return Array.isArray(path) ? path.join('_$_') : path.split(PATH_DELIMITER).join('_$_');
36+
}
37+
_getPath(path: string) {
38+
return path.split('_$_');
39+
}
3840

39-
add<V = any, Options extends SchemaOptions<V> = SchemaOptions<V>>(
40-
path: string | string[],
41-
schema: SchemaDescriptorBuilder | SchemaDescriptor<V, Options>,
42-
) {
43-
const descriptor = isSchemaBuilder(schema) ? schema() : schema;
41+
add<V = any, Options extends SchemaOptions<V> = SchemaOptions<V>>(
42+
path: string | string[],
43+
schema: SchemaDescriptorBuilder | SchemaDescriptor<V, Options>,
44+
) {
45+
const descriptor = isSchemaBuilder(schema) ? schema() : schema;
4446

45-
const pathKey = Array.isArray(path) ? path : path.split(PATH_DELIMITER);
46-
const key = this._getKey(path);
47-
if (!descriptor.options.onFail) descriptor.options.onFail = "throw-pass";
47+
const pathKey = Array.isArray(path) ? path : path.split(PATH_DELIMITER);
48+
const key = this._getKey(path);
49+
if (!descriptor.options.onFail) descriptor.options.onFail = 'throw-pass';
4850

49-
const finalDescriptor = Object.assign({}, this.shadow.options.defaultSchemaOptions, descriptor.options, {
50-
path: pathKey,
51-
datatype: descriptor.datatype,
52-
value: descriptor.value,
53-
}) as unknown as SchemaDescriptor["options"];
51+
const finalDescriptor = Object.assign(
52+
{},
53+
this.shadow.options.defaultSchemaOptions,
54+
descriptor.options,
55+
{
56+
path: pathKey,
57+
datatype: descriptor.datatype,
58+
value: descriptor.value,
59+
},
60+
) as unknown as SchemaDescriptor['options'];
5461

55-
if (typeof finalDescriptor.onValidate === "string") {
56-
finalDescriptor.onValidate = markRaw(parseFunc(finalDescriptor.onValidate)) as any;
57-
}
62+
if (typeof finalDescriptor.onValidate === 'string') {
63+
finalDescriptor.onValidate = markRaw(parseFunc(finalDescriptor.onValidate)) as any;
64+
}
5865

59-
this._descriptors[key] = finalDescriptor;
66+
this._descriptors[key] = finalDescriptor;
6067

61-
if (this.shadow) {
62-
this.shadow.update(
63-
(state) => {
64-
setVal(state, pathKey, descriptor.value);
65-
},
66-
{
67-
validate: "pass",
68-
},
69-
);
70-
}
71-
return descriptor;
72-
}
73-
/**
74-
* 等store的所有计算属性处理完毕再创建schemas
75-
*
76-
*/
77-
build() {
78-
if (this.store) return;
79-
if (!this._descriptors) return;
80-
this.store = this.shadow.shadow(this._descriptors) as unknown as SchemaStore;
81-
}
82-
get<T extends keyof SchemaStore["state"] = keyof SchemaStore["state"]>(path: T): SchemaOptions | undefined {
83-
if (!this.store) return;
84-
return getVal(this.store.state, [this._getKey(path as any)]);
85-
}
86-
has(path: keyof SchemaStore["state"]): boolean {
87-
if (!this.store) return false;
88-
const key = this._getKey(path);
89-
return key in (this.store.state as any);
90-
}
91-
watch() {
92-
// @ts-ignore
93-
return this.store.watch(...arguemnts);
94-
}
95-
getValidator<T extends keyof SchemaStore["state"] = keyof SchemaStore["state"]>(
96-
path: T,
97-
): SchemaValidator<SchemaStore["state"][T]> | undefined {
98-
if (!this.store) return;
99-
const options = this.get(path);
100-
if (!options) return;
101-
return {
102-
validate: options.onValidate!,
103-
onFail: options.onFail!,
104-
message: options.invalidTips!,
105-
};
106-
}
68+
if (this.shadow && descriptor.value !== undefined) {
69+
this.shadow.update(
70+
(state) => {
71+
setVal(state, pathKey, descriptor.value);
72+
},
73+
{
74+
validate: 'pass',
75+
},
76+
);
77+
}
78+
return descriptor;
79+
}
80+
/**
81+
* 等store的所有计算属性处理完毕再创建schemas
82+
*
83+
*/
84+
build() {
85+
if (this.store) return;
86+
if (!this._descriptors) return;
87+
this.store = this.shadow.shadow(this._descriptors) as unknown as SchemaStore;
88+
}
89+
get<T extends keyof SchemaStore['state'] = keyof SchemaStore['state']>(
90+
path: T,
91+
): SchemaOptions | undefined {
92+
if (!this.store) return;
93+
return getVal(this.store.state, [this._getKey(path as any)]);
94+
}
95+
has(path: keyof SchemaStore['state']): boolean {
96+
if (!this.store) return false;
97+
const key = this._getKey(path);
98+
return key in (this.store.state as any);
99+
}
100+
watch() {
101+
// @ts-ignore
102+
return this.store.watch(...arguemnts);
103+
}
104+
getValidator<T extends keyof SchemaStore['state'] = keyof SchemaStore['state']>(
105+
path: T,
106+
): SchemaValidator<SchemaStore['state'][T]> | undefined {
107+
if (!this.store) return;
108+
const options = this.get(path);
109+
if (!options) return;
110+
return {
111+
validate: options.onValidate!,
112+
onFail: options.onFail!,
113+
message: options.invalidTips!,
114+
};
115+
}
107116

108-
addValidator(path: string[], validator: SchemaValidator) {
109-
if (!this.store) return;
110-
const key = this._getKey(path);
111-
this.store.update((state) => {
112-
Object.assign((state as any)[key], {
113-
onValidate: markRaw(validator.validate),
114-
onFail: validator.onFail || "throw-pass",
115-
invalidTips: validator.message,
116-
});
117-
});
118-
}
117+
addValidator(path: string[], validator: SchemaValidator) {
118+
if (!this.store) return;
119+
const key = this._getKey(path);
120+
this.store.update((state) => {
121+
Object.assign((state as any)[key], {
122+
onValidate: markRaw(validator.validate),
123+
onFail: validator.onFail || 'throw-pass',
124+
invalidTips: validator.message,
125+
});
126+
});
127+
}
119128

120-
remove(path: keyof SchemaStore["state"]) {
121-
const key = this._getKey(path);
122-
if (this.store) {
123-
delete (this.store.state as any)[key];
124-
}
125-
}
129+
remove(path: keyof SchemaStore['state']) {
130+
const key = this._getKey(path);
131+
if (this.store) {
132+
delete (this.store.state as any)[key];
133+
}
134+
}
126135

127-
getValues() {
128-
const values: Record<string, any> = {};
129-
Object.entries(this._descriptors || {}).forEach(([key, options]) => {
130-
const path = this._getPath(key);
131-
const name = (options as any).name ?? path.join(PATH_DELIMITER);
132-
this.shadow.peep((state) => {
133-
values[name] = getVal(state, path);
134-
});
135-
});
136-
return values;
137-
}
138-
/**
139-
* 过滤出指定路径的schema
140-
*
141-
* 如:
142-
* schemas.find("user.order")
143-
* schemas.find(["user.order","order"])
144-
*
145-
* @param path
146-
*/
147-
find(path: string | string[]) {
148-
const spath = Array.isArray(path) ? path : path.split(PATH_DELIMITER);
149-
return Object.entries(this.fields)
150-
.filter(([key]) => {
151-
return pathStartsWith(spath, this._getPath(key));
152-
})
153-
.map(([_, options]) => {
154-
return options;
155-
});
156-
}
136+
getValues() {
137+
const values: Record<string, any> = {};
138+
Object.entries(this._descriptors || {}).forEach(([key, options]) => {
139+
const path = this._getPath(key);
140+
const name = (options as any).name ?? path.join(PATH_DELIMITER);
141+
this.shadow.peep((state) => {
142+
values[name] = getVal(state, path);
143+
});
144+
});
145+
return values;
146+
}
147+
/**
148+
* 过滤出指定路径的schema
149+
*
150+
* 如:
151+
* schemas.find("user.order")
152+
* schemas.find(["user.order","order"])
153+
*
154+
* @param path
155+
*/
156+
find(path: string | string[]) {
157+
const spath = Array.isArray(path) ? path : path.split(PATH_DELIMITER);
158+
return Object.entries(this.fields)
159+
.filter(([key]) => {
160+
return pathStartsWith(spath, this._getPath(key));
161+
})
162+
.map(([_, options]) => {
163+
return options;
164+
});
165+
}
157166
}

packages/core/src/schema/schema.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,12 @@ function parseSchemaOptions(args: any[]): SchemaArgs {
101101
}
102102

103103
export const schema = function () {
104-
const args = parseSchemaOptions([...arguments]);
105-
const value = arguments[0];
104+
const [initial, options] =
105+
arguments.length === 1 && typeof arguments[0] === 'object'
106+
? [undefined, arguments[0]]
107+
: [...arguments];
108+
const args = parseSchemaOptions([initial, options]);
109+
const value = initial;
106110
const datatype = Array.isArray(value) ? 'array' : typeof value;
107111
const builder = () => ({
108112
value,

packages/core/src/schema/types/index.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,17 @@ export interface SchemaDescriptorBuilder<Value = any, State = Dict> {
284284
(): SchemaDescriptor<Value, State>;
285285
}
286286

287-
export type SchemaBuilder<Value = any> = <T = Value>(
288-
value: T,
289-
options?: ComputedableSchemaOptions<Value>,
290-
) => SchemaDescriptorBuilder<ToRawType<T>>;
287+
// export type SchemaBuilder<Value = any> = <T = Value>(
288+
// value: T,
289+
// options?: ComputedableSchemaOptions<Value>,
290+
// ) => SchemaDescriptorBuilder<ToRawType<T>>;
291+
292+
export interface SchemaBuilder<Value = any> {
293+
<T = Value>(value: T, options?: ComputedableSchemaOptions<Value>): SchemaDescriptorBuilder<
294+
ToRawType<T>
295+
>;
296+
(options?: ComputedableSchemaOptions<Value>): SchemaDescriptorBuilder<ToRawType<Value>>;
297+
}
291298

292299
export type ConfigurableState<State extends Dict> = {
293300
[Key in SchemaKeyPaths<State>]: GetTypeByPath<ComputedState<State>, Key>;

0 commit comments

Comments
 (0)