glass-easel-miniprogram-adapter 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +4 -0
- package/dist/glass_easel_miniprogram_adapter.d.ts +872 -1
- package/dist/glass_easel_miniprogram_adapter.es.js +2 -0
- package/dist/glass_easel_miniprogram_adapter.es.js.map +1 -0
- package/dist/glass_easel_miniprogram_adapter.js +2 -2
- package/dist/glass_easel_miniprogram_adapter.js.map +1 -1
- package/jest.config.js +7 -4
- package/package.json +8 -6
- package/rollup.config.ts +83 -0
- package/src/backend.ts +7 -3
- package/src/behavior.ts +8 -2
- package/src/builder/base_behavior_builder.ts +437 -0
- package/src/builder/behavior_builder.ts +265 -0
- package/src/builder/component_builder.ts +337 -0
- package/src/builder/index.ts +2 -0
- package/src/builder/type_utils.ts +98 -0
- package/src/component.ts +10 -7
- package/src/env.ts +73 -0
- package/src/index.ts +3 -77
- package/src/intersection.ts +2 -2
- package/src/media_query.ts +4 -6
- package/src/selector_query.ts +3 -3
- package/src/space.ts +11 -1030
- package/src/types.ts +7 -5
- package/tests/base/env.ts +1 -1
- package/tests/env.test.ts +3 -3
- package/tests/selector.test.ts +137 -14
- package/tests/space.test.ts +8 -14
- package/tsconfig.json +1 -3
- package/dist/types/src/backend.d.ts +0 -59
- package/dist/types/src/backend.d.ts.map +0 -1
- package/dist/types/src/behavior.d.ts +0 -35
- package/dist/types/src/behavior.d.ts.map +0 -1
- package/dist/types/src/component.d.ts +0 -170
- package/dist/types/src/component.d.ts.map +0 -1
- package/dist/types/src/index.d.ts +0 -58
- package/dist/types/src/index.d.ts.map +0 -1
- package/dist/types/src/intersection.d.ts +0 -24
- package/dist/types/src/intersection.d.ts.map +0 -1
- package/dist/types/src/media_query.d.ts +0 -13
- package/dist/types/src/media_query.d.ts.map +0 -1
- package/dist/types/src/selector_query.d.ts +0 -98
- package/dist/types/src/selector_query.d.ts.map +0 -1
- package/dist/types/src/space.d.ts +0 -369
- package/dist/types/src/space.d.ts.map +0 -1
- package/dist/types/src/types.d.ts +0 -77
- package/dist/types/src/types.d.ts.map +0 -1
- package/dist/types/src/utils.d.ts +0 -2
- package/dist/types/src/utils.d.ts.map +0 -1
- package/dist/types/tests/base/env.d.ts +0 -3
- package/dist/types/tests/base/env.d.ts.map +0 -1
- package/dist/types/tests/data_update.test.d.ts +0 -2
- package/dist/types/tests/data_update.test.d.ts.map +0 -1
- package/dist/types/tests/env.test.d.ts +0 -2
- package/dist/types/tests/env.test.d.ts.map +0 -1
- package/dist/types/tests/selector.test.d.ts +0 -2
- package/dist/types/tests/selector.test.d.ts.map +0 -1
- package/dist/types/tests/space.test.d.ts +0 -2
- package/dist/types/tests/space.test.d.ts.map +0 -1
- package/dist/types/tests/trait_behavior.test.d.ts +0 -2
- package/dist/types/tests/trait_behavior.test.d.ts.map +0 -1
- package/webpack.config.js +0 -79
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
2
|
+
|
|
3
|
+
import { BaseBehaviorBuilder } from './base_behavior_builder'
|
|
4
|
+
import { Behavior } from '../behavior'
|
|
5
|
+
import type { BehaviorDefinition, utils as typeUtils } from '../types'
|
|
6
|
+
import type { DefinitionFilter, GeneralBehavior } from '../behavior'
|
|
7
|
+
import type { AllData, Component, GeneralComponent } from '../component'
|
|
8
|
+
import type { CodeSpace } from '../space'
|
|
9
|
+
import type { ResolveBehaviorBuilder, BuilderContext } from './type_utils'
|
|
10
|
+
|
|
11
|
+
type Empty = typeUtils.Empty
|
|
12
|
+
type DataList = typeUtils.DataList
|
|
13
|
+
type PropertyList = typeUtils.PropertyList
|
|
14
|
+
type PropertyType = typeUtils.PropertyType
|
|
15
|
+
type PropertyTypeToValueType<T extends PropertyType> = typeUtils.PropertyTypeToValueType<T>
|
|
16
|
+
type MethodList = typeUtils.MethodList
|
|
17
|
+
type ChainingFilterType = typeUtils.ChainingFilterType
|
|
18
|
+
type ComponentMethod = typeUtils.ComponentMethod
|
|
19
|
+
type TaggedMethod<Fn extends ComponentMethod> = typeUtils.TaggedMethod<Fn>
|
|
20
|
+
type ChainingFilterFunc<
|
|
21
|
+
TAddedFields extends { [key: string]: any },
|
|
22
|
+
TRemovedFields extends string = never,
|
|
23
|
+
> = typeUtils.ChainingFilterFunc<TAddedFields, TRemovedFields>
|
|
24
|
+
|
|
25
|
+
export class BehaviorBuilder<
|
|
26
|
+
TPrevData extends DataList = Empty,
|
|
27
|
+
TData extends DataList = Empty,
|
|
28
|
+
TProperty extends PropertyList = Empty,
|
|
29
|
+
TMethod extends MethodList = Empty,
|
|
30
|
+
TChainingFilter extends ChainingFilterType = never,
|
|
31
|
+
TPendingChainingFilter extends ChainingFilterType = never,
|
|
32
|
+
TComponentExport = never,
|
|
33
|
+
> extends BaseBehaviorBuilder<
|
|
34
|
+
TPrevData,
|
|
35
|
+
TData,
|
|
36
|
+
TProperty,
|
|
37
|
+
TMethod,
|
|
38
|
+
TChainingFilter,
|
|
39
|
+
TPendingChainingFilter,
|
|
40
|
+
TComponentExport
|
|
41
|
+
> {
|
|
42
|
+
private _$definitionFilter: DefinitionFilter | undefined
|
|
43
|
+
|
|
44
|
+
/** @internal */
|
|
45
|
+
static create(codeSpace: CodeSpace): BehaviorBuilder {
|
|
46
|
+
const ret = new BehaviorBuilder()
|
|
47
|
+
ret._$codeSpace = codeSpace
|
|
48
|
+
ret._$ = codeSpace.getComponentSpace().defineWithMethodCaller()
|
|
49
|
+
return ret
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Define a chaining filter */
|
|
53
|
+
chainingFilter<
|
|
54
|
+
TAddedFields extends { [key: string]: any },
|
|
55
|
+
TRemovedFields extends string = never,
|
|
56
|
+
>(
|
|
57
|
+
func: ChainingFilterFunc<TAddedFields, TRemovedFields>,
|
|
58
|
+
): ResolveBehaviorBuilder<
|
|
59
|
+
BehaviorBuilder<
|
|
60
|
+
TPrevData,
|
|
61
|
+
TData,
|
|
62
|
+
TProperty,
|
|
63
|
+
TMethod,
|
|
64
|
+
TChainingFilter,
|
|
65
|
+
{
|
|
66
|
+
add: TAddedFields
|
|
67
|
+
remove: TRemovedFields
|
|
68
|
+
},
|
|
69
|
+
TComponentExport
|
|
70
|
+
>,
|
|
71
|
+
TChainingFilter
|
|
72
|
+
> {
|
|
73
|
+
this._$.chainingFilter(func as any)
|
|
74
|
+
return this as any
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Use another behavior */
|
|
78
|
+
behavior<
|
|
79
|
+
UData extends DataList,
|
|
80
|
+
UProperty extends PropertyList,
|
|
81
|
+
UMethod extends MethodList,
|
|
82
|
+
UChainingFilter extends ChainingFilterType,
|
|
83
|
+
>(
|
|
84
|
+
behavior: Behavior<UData, UProperty, UMethod, UChainingFilter>,
|
|
85
|
+
): ResolveBehaviorBuilder<
|
|
86
|
+
BehaviorBuilder<
|
|
87
|
+
TPrevData,
|
|
88
|
+
TData & UData,
|
|
89
|
+
TProperty & UProperty,
|
|
90
|
+
TMethod & UMethod,
|
|
91
|
+
UChainingFilter,
|
|
92
|
+
TPendingChainingFilter,
|
|
93
|
+
TComponentExport
|
|
94
|
+
>,
|
|
95
|
+
UChainingFilter
|
|
96
|
+
> {
|
|
97
|
+
this._$parents.push(behavior as GeneralBehavior)
|
|
98
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
99
|
+
this._$ = this._$.behavior(behavior._$)
|
|
100
|
+
return this as any
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Set the export value when the component is being selected */
|
|
104
|
+
override export<TNewComponentExport>(
|
|
105
|
+
f: (this: GeneralComponent, source: GeneralComponent | null) => TNewComponentExport,
|
|
106
|
+
): ResolveBehaviorBuilder<
|
|
107
|
+
BehaviorBuilder<
|
|
108
|
+
TPrevData,
|
|
109
|
+
TData,
|
|
110
|
+
TProperty,
|
|
111
|
+
TMethod,
|
|
112
|
+
TChainingFilter,
|
|
113
|
+
TPendingChainingFilter,
|
|
114
|
+
TNewComponentExport
|
|
115
|
+
>,
|
|
116
|
+
TChainingFilter
|
|
117
|
+
> {
|
|
118
|
+
return super.export(f) as any
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Add some template data fields
|
|
123
|
+
*
|
|
124
|
+
* It does not support raw data, but a `gen` function which returns the new data fields.
|
|
125
|
+
* The `gen` function executes once during component creation.
|
|
126
|
+
*/
|
|
127
|
+
override data<T extends DataList>(
|
|
128
|
+
gen: () => typeUtils.NewFieldList<AllData<TData, TProperty>, T>,
|
|
129
|
+
): ResolveBehaviorBuilder<
|
|
130
|
+
BehaviorBuilder<
|
|
131
|
+
T,
|
|
132
|
+
TData & T,
|
|
133
|
+
TProperty,
|
|
134
|
+
TMethod,
|
|
135
|
+
TChainingFilter,
|
|
136
|
+
TPendingChainingFilter,
|
|
137
|
+
TComponentExport
|
|
138
|
+
>,
|
|
139
|
+
TChainingFilter
|
|
140
|
+
> {
|
|
141
|
+
return super.data(gen) as any
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Add a single property
|
|
146
|
+
*
|
|
147
|
+
* The property name should be different from other properties.
|
|
148
|
+
*/
|
|
149
|
+
override property<N extends string, T extends PropertyType, V extends PropertyTypeToValueType<T>>(
|
|
150
|
+
name: N,
|
|
151
|
+
def: N extends keyof (TData & TProperty) ? never : typeUtils.PropertyListItem<T, V>,
|
|
152
|
+
): ResolveBehaviorBuilder<
|
|
153
|
+
BehaviorBuilder<
|
|
154
|
+
TPrevData,
|
|
155
|
+
TData,
|
|
156
|
+
TProperty & Record<N, unknown extends V ? T : typeUtils.PropertyOption<T, V>>,
|
|
157
|
+
TMethod,
|
|
158
|
+
TChainingFilter,
|
|
159
|
+
TPendingChainingFilter,
|
|
160
|
+
TComponentExport
|
|
161
|
+
>,
|
|
162
|
+
TChainingFilter
|
|
163
|
+
> {
|
|
164
|
+
return super.property(name, def) as any
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Add some public methods
|
|
169
|
+
*
|
|
170
|
+
* The public method can be used as an event handler, and can be visited in component instance.
|
|
171
|
+
*/
|
|
172
|
+
override methods<T extends MethodList>(
|
|
173
|
+
funcs: T & ThisType<Component<TData, TProperty, TMethod & T, any>>,
|
|
174
|
+
): ResolveBehaviorBuilder<
|
|
175
|
+
BehaviorBuilder<
|
|
176
|
+
TPrevData,
|
|
177
|
+
TData,
|
|
178
|
+
TProperty,
|
|
179
|
+
TMethod & T,
|
|
180
|
+
TChainingFilter,
|
|
181
|
+
TPendingChainingFilter,
|
|
182
|
+
TComponentExport
|
|
183
|
+
>,
|
|
184
|
+
TChainingFilter
|
|
185
|
+
> {
|
|
186
|
+
return super.methods(funcs) as any
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Execute a function while component instance creation
|
|
191
|
+
*
|
|
192
|
+
* A `BuilderContext` is provided to tweak the component creation progress.
|
|
193
|
+
* The return value is used as the "export" value of the behavior,
|
|
194
|
+
* which can be imported by other behaviors.
|
|
195
|
+
*/
|
|
196
|
+
override init<TExport extends Record<string, TaggedMethod<(...args: any[]) => any>> | void>(
|
|
197
|
+
func: (
|
|
198
|
+
this: Component<TData, TProperty, TMethod, TComponentExport>,
|
|
199
|
+
builderContext: BuilderContext<
|
|
200
|
+
TPrevData,
|
|
201
|
+
TProperty,
|
|
202
|
+
Component<TData, TProperty, TMethod, TComponentExport>
|
|
203
|
+
>,
|
|
204
|
+
) => TExport,
|
|
205
|
+
// eslint-disable-next-line function-paren-newline
|
|
206
|
+
): ResolveBehaviorBuilder<
|
|
207
|
+
BehaviorBuilder<
|
|
208
|
+
TPrevData,
|
|
209
|
+
TData,
|
|
210
|
+
TProperty,
|
|
211
|
+
TMethod,
|
|
212
|
+
TChainingFilter,
|
|
213
|
+
TPendingChainingFilter,
|
|
214
|
+
TComponentExport
|
|
215
|
+
>,
|
|
216
|
+
TChainingFilter
|
|
217
|
+
> {
|
|
218
|
+
return super.init(func) as any
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** Apply a classic definition object */
|
|
222
|
+
override definition<
|
|
223
|
+
TNewData extends DataList = Empty,
|
|
224
|
+
TNewProperty extends PropertyList = Empty,
|
|
225
|
+
TNewMethod extends MethodList = Empty,
|
|
226
|
+
TNewComponentExport = never,
|
|
227
|
+
>(
|
|
228
|
+
def: BehaviorDefinition<TNewData, TNewProperty, TNewMethod, TNewComponentExport> &
|
|
229
|
+
ThisType<
|
|
230
|
+
Component<
|
|
231
|
+
TData & TNewData,
|
|
232
|
+
TProperty & TNewProperty,
|
|
233
|
+
TMethod & TNewMethod,
|
|
234
|
+
TNewComponentExport
|
|
235
|
+
>
|
|
236
|
+
>,
|
|
237
|
+
): ResolveBehaviorBuilder<
|
|
238
|
+
BehaviorBuilder<
|
|
239
|
+
TPrevData,
|
|
240
|
+
TData & TNewData,
|
|
241
|
+
TProperty & TNewProperty,
|
|
242
|
+
TMethod & TNewMethod,
|
|
243
|
+
TChainingFilter,
|
|
244
|
+
TPendingChainingFilter,
|
|
245
|
+
TNewComponentExport
|
|
246
|
+
>,
|
|
247
|
+
TChainingFilter
|
|
248
|
+
> {
|
|
249
|
+
super.definition(def)
|
|
250
|
+
if (def.definitionFilter) this._$definitionFilter = def.definitionFilter
|
|
251
|
+
return this as any
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Finish the behavior definition process
|
|
256
|
+
*/
|
|
257
|
+
register(): Behavior<TData, TProperty, TMethod, TPendingChainingFilter, TComponentExport> {
|
|
258
|
+
return new Behavior(
|
|
259
|
+
this._$.registerBehavior(),
|
|
260
|
+
this._$parents,
|
|
261
|
+
this._$definitionFilter,
|
|
262
|
+
this._$export,
|
|
263
|
+
)
|
|
264
|
+
}
|
|
265
|
+
}
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
2
|
+
|
|
3
|
+
import * as glassEasel from 'glass-easel'
|
|
4
|
+
import { BaseBehaviorBuilder } from './base_behavior_builder'
|
|
5
|
+
import { ComponentType } from '../behavior'
|
|
6
|
+
import { ComponentProto } from '../component'
|
|
7
|
+
import type {
|
|
8
|
+
ComponentDefinitionOptions,
|
|
9
|
+
ComponentDefinition,
|
|
10
|
+
PageDefinition,
|
|
11
|
+
utils as typeUtils,
|
|
12
|
+
} from '../types'
|
|
13
|
+
import type { Behavior, GeneralBehavior } from '../behavior'
|
|
14
|
+
import type { AllData, Component, GeneralComponent } from '../component'
|
|
15
|
+
import type { CodeSpace } from '../space'
|
|
16
|
+
import type { ResolveBehaviorBuilder, BuilderContext } from './type_utils'
|
|
17
|
+
|
|
18
|
+
type Empty = typeUtils.Empty
|
|
19
|
+
type DataList = typeUtils.DataList
|
|
20
|
+
type PropertyList = typeUtils.PropertyList
|
|
21
|
+
type PropertyType = typeUtils.PropertyType
|
|
22
|
+
type PropertyTypeToValueType<T extends PropertyType> = typeUtils.PropertyTypeToValueType<T>
|
|
23
|
+
type MethodList = typeUtils.MethodList
|
|
24
|
+
type ChainingFilterType = typeUtils.ChainingFilterType
|
|
25
|
+
type ComponentMethod = typeUtils.ComponentMethod
|
|
26
|
+
type TaggedMethod<Fn extends ComponentMethod> = typeUtils.TaggedMethod<Fn>
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* A direct way to create a component
|
|
30
|
+
*/
|
|
31
|
+
export class ComponentBuilder<
|
|
32
|
+
TPrevData extends DataList = Empty,
|
|
33
|
+
TData extends DataList = Empty,
|
|
34
|
+
TProperty extends PropertyList = Empty,
|
|
35
|
+
TMethod extends MethodList = Empty,
|
|
36
|
+
TChainingFilter extends ChainingFilterType = never,
|
|
37
|
+
TPendingChainingFilter extends ChainingFilterType = never,
|
|
38
|
+
TComponentExport = never,
|
|
39
|
+
> extends BaseBehaviorBuilder<
|
|
40
|
+
TPrevData,
|
|
41
|
+
TData,
|
|
42
|
+
TProperty,
|
|
43
|
+
TMethod,
|
|
44
|
+
TChainingFilter,
|
|
45
|
+
TPendingChainingFilter,
|
|
46
|
+
TComponentExport
|
|
47
|
+
> {
|
|
48
|
+
private _$is!: string
|
|
49
|
+
private _$alias?: string[]
|
|
50
|
+
private _$options?: ComponentDefinitionOptions
|
|
51
|
+
private _$proto?: ComponentProto<TData, TProperty, TMethod, TComponentExport>
|
|
52
|
+
|
|
53
|
+
/** @internal */
|
|
54
|
+
static create(codeSpace: CodeSpace, is: string, alias?: string[]) {
|
|
55
|
+
const ret = new ComponentBuilder()
|
|
56
|
+
const overallBehavior = codeSpace._$overallBehavior
|
|
57
|
+
ret._$codeSpace = codeSpace
|
|
58
|
+
ret._$ = codeSpace.getComponentSpace().defineWithMethodCaller(is || '')
|
|
59
|
+
ret._$is = is || ''
|
|
60
|
+
ret._$alias = alias
|
|
61
|
+
ret._$.methodCallerInit(function () {
|
|
62
|
+
const originalCaller = this as unknown as glassEasel.GeneralComponent
|
|
63
|
+
let proto = ret._$proto
|
|
64
|
+
if (proto === undefined) {
|
|
65
|
+
const methods = originalCaller.getComponentDefinition().behavior.getMethods()
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
67
|
+
proto = ret._$proto = new ComponentProto(methods, ret._$export) as any
|
|
68
|
+
}
|
|
69
|
+
const caller = proto!.derive()
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
71
|
+
caller._$ = originalCaller as any
|
|
72
|
+
return caller
|
|
73
|
+
})
|
|
74
|
+
if (overallBehavior) ret._$.behavior(overallBehavior)
|
|
75
|
+
return ret
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Set the component options
|
|
80
|
+
*
|
|
81
|
+
* If called multiple times, only the latest call is valid.
|
|
82
|
+
*/
|
|
83
|
+
options(options: ComponentDefinitionOptions): ResolveBehaviorBuilder<this, TChainingFilter> {
|
|
84
|
+
this._$options = options
|
|
85
|
+
return this as any
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Use another behavior */
|
|
89
|
+
behavior<
|
|
90
|
+
UData extends DataList,
|
|
91
|
+
UProperty extends PropertyList,
|
|
92
|
+
UMethod extends MethodList,
|
|
93
|
+
UChainingFilter extends ChainingFilterType,
|
|
94
|
+
UComponentExport,
|
|
95
|
+
>(
|
|
96
|
+
behavior: Behavior<UData, UProperty, UMethod, UChainingFilter, UComponentExport>,
|
|
97
|
+
): ResolveBehaviorBuilder<
|
|
98
|
+
ComponentBuilder<
|
|
99
|
+
TPrevData,
|
|
100
|
+
TData & UData,
|
|
101
|
+
TProperty & UProperty,
|
|
102
|
+
TMethod & UMethod,
|
|
103
|
+
UChainingFilter,
|
|
104
|
+
TPendingChainingFilter,
|
|
105
|
+
UComponentExport
|
|
106
|
+
>,
|
|
107
|
+
UChainingFilter
|
|
108
|
+
> {
|
|
109
|
+
this._$parents.push(behavior as GeneralBehavior)
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
111
|
+
this._$ = this._$.behavior(behavior._$)
|
|
112
|
+
if (behavior._$export) {
|
|
113
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
114
|
+
this._$export = behavior._$export as any
|
|
115
|
+
}
|
|
116
|
+
return this as any
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Set the export value when the component is being selected */
|
|
120
|
+
override export<TNewComponentExport>(
|
|
121
|
+
f: (this: GeneralComponent, source: GeneralComponent | null) => TNewComponentExport,
|
|
122
|
+
): ResolveBehaviorBuilder<
|
|
123
|
+
ComponentBuilder<
|
|
124
|
+
TPrevData,
|
|
125
|
+
TData,
|
|
126
|
+
TProperty,
|
|
127
|
+
TMethod,
|
|
128
|
+
TChainingFilter,
|
|
129
|
+
TPendingChainingFilter,
|
|
130
|
+
TNewComponentExport
|
|
131
|
+
>,
|
|
132
|
+
TChainingFilter
|
|
133
|
+
> {
|
|
134
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
135
|
+
this._$export = f as any
|
|
136
|
+
return this as any
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Add some template data fields
|
|
141
|
+
*
|
|
142
|
+
* It does not support raw data, but a `gen` function which returns the new data fields.
|
|
143
|
+
* The `gen` function executes once during component creation.
|
|
144
|
+
*/
|
|
145
|
+
override data<T extends DataList>(
|
|
146
|
+
gen: () => typeUtils.NewFieldList<AllData<TData, TProperty>, T>,
|
|
147
|
+
): ResolveBehaviorBuilder<
|
|
148
|
+
ComponentBuilder<
|
|
149
|
+
T,
|
|
150
|
+
TData & T,
|
|
151
|
+
TProperty,
|
|
152
|
+
TMethod,
|
|
153
|
+
TChainingFilter,
|
|
154
|
+
TPendingChainingFilter,
|
|
155
|
+
TComponentExport
|
|
156
|
+
>,
|
|
157
|
+
TChainingFilter
|
|
158
|
+
> {
|
|
159
|
+
return super.data(gen) as any
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Add a single property
|
|
164
|
+
*
|
|
165
|
+
* The property name should be different from other properties.
|
|
166
|
+
*/
|
|
167
|
+
override property<N extends string, T extends PropertyType, V extends PropertyTypeToValueType<T>>(
|
|
168
|
+
name: N,
|
|
169
|
+
def: N extends keyof (TData & TProperty) ? never : typeUtils.PropertyListItem<T, V>,
|
|
170
|
+
): ResolveBehaviorBuilder<
|
|
171
|
+
ComponentBuilder<
|
|
172
|
+
TPrevData,
|
|
173
|
+
TData,
|
|
174
|
+
TProperty & Record<N, unknown extends V ? T : typeUtils.PropertyOption<T, V>>,
|
|
175
|
+
TMethod,
|
|
176
|
+
TChainingFilter,
|
|
177
|
+
TPendingChainingFilter,
|
|
178
|
+
TComponentExport
|
|
179
|
+
>,
|
|
180
|
+
TChainingFilter
|
|
181
|
+
> {
|
|
182
|
+
return super.property(name, def) as any
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Add some public methods
|
|
187
|
+
*
|
|
188
|
+
* The public method can be used as an event handler, and can be visited in component instance.
|
|
189
|
+
*/
|
|
190
|
+
override methods<T extends MethodList>(
|
|
191
|
+
funcs: T & ThisType<Component<TData, TProperty, TMethod & T, any>>,
|
|
192
|
+
): ResolveBehaviorBuilder<
|
|
193
|
+
ComponentBuilder<
|
|
194
|
+
TPrevData,
|
|
195
|
+
TData,
|
|
196
|
+
TProperty,
|
|
197
|
+
TMethod & T,
|
|
198
|
+
TChainingFilter,
|
|
199
|
+
TPendingChainingFilter,
|
|
200
|
+
TComponentExport
|
|
201
|
+
>,
|
|
202
|
+
TChainingFilter
|
|
203
|
+
> {
|
|
204
|
+
return super.methods(funcs) as any
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Execute a function while component instance creation
|
|
209
|
+
*
|
|
210
|
+
* A `BuilderContext` is provided to tweak the component creation progress.
|
|
211
|
+
* The return value is used as the "export" value of the behavior,
|
|
212
|
+
* which can be imported by other behaviors.
|
|
213
|
+
*/
|
|
214
|
+
override init<TExport extends Record<string, TaggedMethod<(...args: any[]) => any>> | void>(
|
|
215
|
+
func: (
|
|
216
|
+
this: Component<TData, TProperty, TMethod, TComponentExport>,
|
|
217
|
+
builderContext: BuilderContext<
|
|
218
|
+
TPrevData,
|
|
219
|
+
TProperty,
|
|
220
|
+
Component<TData, TProperty, TMethod, TComponentExport>
|
|
221
|
+
>,
|
|
222
|
+
) => TExport,
|
|
223
|
+
// eslint-disable-next-line function-paren-newline
|
|
224
|
+
): ResolveBehaviorBuilder<
|
|
225
|
+
ComponentBuilder<
|
|
226
|
+
TPrevData,
|
|
227
|
+
TData,
|
|
228
|
+
TProperty,
|
|
229
|
+
TMethod,
|
|
230
|
+
TChainingFilter,
|
|
231
|
+
TPendingChainingFilter,
|
|
232
|
+
TComponentExport
|
|
233
|
+
>,
|
|
234
|
+
TChainingFilter
|
|
235
|
+
> {
|
|
236
|
+
return super.init(func) as any
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/** Apply a classic definition object */
|
|
240
|
+
override definition<
|
|
241
|
+
TNewData extends DataList = Empty,
|
|
242
|
+
TNewProperty extends PropertyList = Empty,
|
|
243
|
+
TNewMethod extends MethodList = Empty,
|
|
244
|
+
TNewComponentExport = never,
|
|
245
|
+
>(
|
|
246
|
+
def: ComponentDefinition<TNewData, TNewProperty, TNewMethod, TNewComponentExport> &
|
|
247
|
+
ThisType<
|
|
248
|
+
Component<
|
|
249
|
+
TData & TNewData,
|
|
250
|
+
TProperty & TNewProperty,
|
|
251
|
+
TMethod & TNewMethod,
|
|
252
|
+
TNewComponentExport
|
|
253
|
+
>
|
|
254
|
+
>,
|
|
255
|
+
): ResolveBehaviorBuilder<
|
|
256
|
+
ComponentBuilder<
|
|
257
|
+
TPrevData,
|
|
258
|
+
TData & TNewData,
|
|
259
|
+
TProperty & TNewProperty,
|
|
260
|
+
TMethod & TNewMethod,
|
|
261
|
+
TChainingFilter,
|
|
262
|
+
TPendingChainingFilter,
|
|
263
|
+
TNewComponentExport
|
|
264
|
+
>,
|
|
265
|
+
TChainingFilter
|
|
266
|
+
> {
|
|
267
|
+
super.definition(def)
|
|
268
|
+
if (def.options) this.options(def.options)
|
|
269
|
+
return this as any
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
pageDefinition<TNewData extends DataList, TNewExtraFields extends { [k: PropertyKey]: any }>(
|
|
273
|
+
def: PageDefinition<TNewData, TNewExtraFields> &
|
|
274
|
+
ThisType<Component<TData & TNewData, TProperty, TMethod & TNewExtraFields, undefined>>,
|
|
275
|
+
): ResolveBehaviorBuilder<
|
|
276
|
+
ComponentBuilder<
|
|
277
|
+
TPrevData,
|
|
278
|
+
TData & TNewData,
|
|
279
|
+
TProperty,
|
|
280
|
+
TMethod & TNewExtraFields,
|
|
281
|
+
TChainingFilter,
|
|
282
|
+
TPendingChainingFilter,
|
|
283
|
+
TComponentExport
|
|
284
|
+
>,
|
|
285
|
+
TChainingFilter
|
|
286
|
+
> {
|
|
287
|
+
const freeData = Object.create(null) as { [k: string]: any }
|
|
288
|
+
const compDef = {
|
|
289
|
+
methods: {},
|
|
290
|
+
} as { [k: string]: any }
|
|
291
|
+
const keys = Object.keys(def)
|
|
292
|
+
for (let i = 0; i < keys.length; i += 1) {
|
|
293
|
+
const k = keys[i]!
|
|
294
|
+
if (k === 'data' || k === 'options' || k === 'behaviors') {
|
|
295
|
+
compDef[k] = def[k]
|
|
296
|
+
} else if (typeof def[k] === 'function') {
|
|
297
|
+
;(compDef.methods as { [k: string]: unknown })[k] = def[k] as unknown
|
|
298
|
+
} else {
|
|
299
|
+
;(freeData as { [k: string]: unknown })[k] = def[k]
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
this.definition(compDef)
|
|
303
|
+
this._$.init(function () {
|
|
304
|
+
Object.assign(this, glassEasel.dataUtils.simpleDeepCopy(freeData))
|
|
305
|
+
})
|
|
306
|
+
return this as any
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Finish the component definition process
|
|
311
|
+
*/
|
|
312
|
+
register(): ComponentType<TData, TProperty, TMethod, TComponentExport> {
|
|
313
|
+
const is = this._$is
|
|
314
|
+
const codeSpace = this._$codeSpace
|
|
315
|
+
|
|
316
|
+
// processing common fields
|
|
317
|
+
const [options, styleIsolation] = codeSpace.prepareComponentOptions(is, this._$options)
|
|
318
|
+
this._$.options(options)
|
|
319
|
+
const staticConfig = codeSpace.getComponentStaticConfig(is)
|
|
320
|
+
const using = staticConfig?.usingComponents
|
|
321
|
+
const generics = staticConfig?.componentGenerics
|
|
322
|
+
const placeholder = staticConfig?.componentPlaceholder
|
|
323
|
+
if (using) this._$.usingComponents(using)
|
|
324
|
+
if (generics) this._$.generics(generics)
|
|
325
|
+
if (placeholder) this._$.placeholders(placeholder)
|
|
326
|
+
const template = codeSpace.getCompiledTemplate(is)
|
|
327
|
+
if (template) this._$.template(template)
|
|
328
|
+
|
|
329
|
+
// do registration
|
|
330
|
+
codeSpace._$styleIsolationMap[is] = styleIsolation
|
|
331
|
+
const compDef = this._$.registerComponent()
|
|
332
|
+
this._$alias?.forEach((alias) => {
|
|
333
|
+
this._$codeSpace.getComponentSpace().exportComponent(alias, this._$is)
|
|
334
|
+
})
|
|
335
|
+
return new ComponentType(compDef)
|
|
336
|
+
}
|
|
337
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type * as glassEasel from 'glass-easel'
|
|
2
|
+
import type { utils as typeUtils } from '../types'
|
|
3
|
+
import type { ComponentType, GeneralBehavior, TraitBehavior } from '../behavior'
|
|
4
|
+
import type { GeneralComponent } from '../component'
|
|
5
|
+
|
|
6
|
+
export type ResolveBehaviorBuilder<
|
|
7
|
+
B,
|
|
8
|
+
TChainingFilter extends ChainingFilterType,
|
|
9
|
+
> = typeUtils.IsNever<TChainingFilter> extends false
|
|
10
|
+
? TChainingFilter extends ChainingFilterType
|
|
11
|
+
? Omit<B, TChainingFilter['remove']> & TChainingFilter['add']
|
|
12
|
+
: B
|
|
13
|
+
: B
|
|
14
|
+
|
|
15
|
+
type DataList = typeUtils.DataList
|
|
16
|
+
type PropertyList = typeUtils.PropertyList
|
|
17
|
+
type ChainingFilterType = typeUtils.ChainingFilterType
|
|
18
|
+
type ComponentMethod = typeUtils.ComponentMethod
|
|
19
|
+
type TaggedMethod<Fn extends ComponentMethod> = typeUtils.TaggedMethod<Fn>
|
|
20
|
+
|
|
21
|
+
export interface RelationHandler<TTarget, TOut> {
|
|
22
|
+
list(): TTarget[]
|
|
23
|
+
listAsTrait: TOut extends never ? undefined : () => TOut[]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type TraitRelationParams<TOut extends { [key: string]: any }> = {
|
|
27
|
+
target: TraitBehavior<any, TOut>
|
|
28
|
+
type: 'ancestor' | 'descendant' | 'parent' | 'child' | 'parent-common-node' | 'child-common-node'
|
|
29
|
+
linked?: (target: GeneralComponent) => void
|
|
30
|
+
linkChanged?: (target: GeneralComponent) => void
|
|
31
|
+
unlinked?: (target: GeneralComponent) => void
|
|
32
|
+
linkFailed?: (target: GeneralComponent) => void
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type RelationParams = {
|
|
36
|
+
target?: string | ComponentType<any, any, any, any> | GeneralBehavior | TraitBehavior<any>
|
|
37
|
+
type: 'ancestor' | 'descendant' | 'parent' | 'child' | 'parent-common-node' | 'child-common-node'
|
|
38
|
+
linked?: (target: GeneralComponent) => void
|
|
39
|
+
linkChanged?: (target: GeneralComponent) => void
|
|
40
|
+
unlinked?: (target: GeneralComponent) => void
|
|
41
|
+
linkFailed?: (target: GeneralComponent) => void
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type Lifetimes = {
|
|
45
|
+
created: () => void
|
|
46
|
+
attached: () => void
|
|
47
|
+
moved: () => void
|
|
48
|
+
detached: () => void
|
|
49
|
+
ready: () => void
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface BuilderContext<
|
|
53
|
+
TPrevData extends DataList,
|
|
54
|
+
TProperty extends PropertyList,
|
|
55
|
+
TMethodCaller,
|
|
56
|
+
> extends ThisType<TMethodCaller> {
|
|
57
|
+
self: TMethodCaller
|
|
58
|
+
data: typeUtils.Merge<typeUtils.DataWithPropertyValues<TPrevData, TProperty>>
|
|
59
|
+
setData: (newData: Partial<typeUtils.SetDataSetter<TPrevData>>, callback?: () => void) => void
|
|
60
|
+
implement: <TIn extends { [x: string]: any }>(
|
|
61
|
+
traitBehavior: TraitBehavior<TIn, any>,
|
|
62
|
+
impl: TIn,
|
|
63
|
+
) => void
|
|
64
|
+
relation<TOut extends { [key: string]: any }>(
|
|
65
|
+
def: TraitRelationParams<TOut> & ThisType<TMethodCaller>,
|
|
66
|
+
): RelationHandler<any, TOut>
|
|
67
|
+
relation(def: RelationParams & ThisType<TMethodCaller>): RelationHandler<any, never>
|
|
68
|
+
observer<
|
|
69
|
+
P extends typeUtils.ObserverDataPathStrings<
|
|
70
|
+
typeUtils.DataWithPropertyValues<TPrevData, TProperty>
|
|
71
|
+
>,
|
|
72
|
+
V = typeUtils.GetFromObserverPathString<
|
|
73
|
+
typeUtils.DataWithPropertyValues<TPrevData, TProperty>,
|
|
74
|
+
P
|
|
75
|
+
>,
|
|
76
|
+
>(
|
|
77
|
+
paths: P,
|
|
78
|
+
func: (newValue: V) => void,
|
|
79
|
+
): void
|
|
80
|
+
observer<
|
|
81
|
+
P extends typeUtils.ObserverDataPathStrings<
|
|
82
|
+
typeUtils.DataWithPropertyValues<TPrevData, TProperty>
|
|
83
|
+
>[],
|
|
84
|
+
V = {
|
|
85
|
+
[K in keyof P]: typeUtils.GetFromObserverPathString<
|
|
86
|
+
typeUtils.DataWithPropertyValues<TPrevData, TProperty>,
|
|
87
|
+
P[K]
|
|
88
|
+
>
|
|
89
|
+
},
|
|
90
|
+
>(
|
|
91
|
+
paths: readonly [...P],
|
|
92
|
+
func: (...newValues: V extends any[] ? V : never) => void,
|
|
93
|
+
): void
|
|
94
|
+
lifetime: <L extends keyof Lifetimes>(name: L, func: Lifetimes[L]) => void
|
|
95
|
+
pageLifetime: (name: string, func: (...args: any[]) => void) => void
|
|
96
|
+
method: <Fn extends ComponentMethod>(func: Fn) => TaggedMethod<Fn>
|
|
97
|
+
listener: <T>(func: glassEasel.EventListener<T>) => TaggedMethod<glassEasel.EventListener<T>>
|
|
98
|
+
}
|