Skip to content

Commit def9830

Browse files
committed
feat: initial coding
1 parent e9f79c1 commit def9830

File tree

4 files changed

+91
-85
lines changed

4 files changed

+91
-85
lines changed

src/base.ts

+82-83
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { isMiniProgramEnvironment } from '.'
12
import { GeneralFuncType, FuncArr } from './func_arr'
23
import { TraitBehavior, TraitGroup } from './trait_behavior'
34
import {
@@ -156,7 +157,7 @@ class ChainingPolyfillMetadata {
156157
const exportedKey = exportedKeys[j]!
157158
const exportItem = (exported as { [k in string]: unknown })[exportedKey]
158159
if (isTaggedMethod(exportItem)) {
159-
comp.methods[exportedKey] = exportItem
160+
comp[exportedKey] = exportItem
160161
}
161162
}
162163
}
@@ -175,55 +176,6 @@ class ChainingPolyfillMetadata {
175176
}
176177
}
177178

178-
const getChainingPolyfillMetadata = (comp: GeneralComponent): ChainingPolyfillMetadata => {
179-
return comp._$chainingPolyfill
180-
}
181-
182-
// const takeChainingPolyfillInitData = (
183-
// comp: GeneralComponent,
184-
// ): ChainingPolyfillInitData | undefined => {
185-
// const id = comp.data._$chainingPolyfillId
186-
// if (!(id >= 0)) return undefined
187-
// comp.data._$chainingPolyfillId = -1
188-
// const initData = initDataMap[id]
189-
// const cloneMap = (src: { [k: string]: FuncArr<any> }) => {
190-
// const dest = {} as typeof src
191-
// const keys = Object.keys(src)
192-
// for (let i = 0; i < keys.length; i += 1) {
193-
// const key = keys[i]!
194-
// dest[key] = src[key].clone()
195-
// }
196-
// return dest
197-
// }
198-
// return {
199-
// lifetimes: cloneMap(initData.lifetimes),
200-
// pageLifetimes: cloneMap(initData.pageLifetimes),
201-
// observers: cloneMap(initData.observers),
202-
// initFuncs: initData.initFuncs.clone(),
203-
// }
204-
// }
205-
206-
const generateChainingPolyfillBehavior = (initData: ChainingPolyfillInitData) => {
207-
return Behavior({
208-
lifetimes: {
209-
created() {
210-
const chainingPolyfillMetadata = new ChainingPolyfillMetadata(initData)
211-
;(this as any)._$chainingPolyfill = chainingPolyfillMetadata
212-
const ctx = chainingPolyfillMetadata.generateBuilderContext(this as any)
213-
initData.initFuncs.call(this, [ctx, chainingPolyfillMetadata])
214-
chainingPolyfillMetadata.setInitDone()
215-
},
216-
},
217-
methods: {
218-
traitBehavior<TOut extends { [x: string]: any }>(
219-
traitBehavior: TraitBehavior<any, TOut>,
220-
): TOut | undefined {
221-
return getChainingPolyfillMetadata(this).traitGroup.get(traitBehavior)
222-
},
223-
},
224-
})
225-
}
226-
227179
export class BaseBehaviorBuilder<
228180
TPrevData extends DataList = Empty,
229181
TData extends DataList = Empty,
@@ -234,6 +186,7 @@ export class BaseBehaviorBuilder<
234186
TComponentExport = never,
235187
TExtraThisFields extends DataList = Empty,
236188
> {
189+
private _$instanceMap: WeakMap<GeneralComponent, ChainingPolyfillMetadata> = new WeakMap()
237190
private _$initData = {
238191
lifetimes: {},
239192
pageLifetimes: {},
@@ -244,43 +197,83 @@ export class BaseBehaviorBuilder<
244197
data: {} as DataList,
245198
properties: {} as WechatMiniprogram.Behavior.PropertyOption,
246199
methods: {} as MethodList,
247-
behaviors: [generateChainingPolyfillBehavior(this._$initData)],
248-
lifetimes: {
200+
behaviors: [] as WechatMiniprogram.Behavior.BehaviorIdentifier<any, any, any, any>[],
201+
lifetimes: {} as Lifetimes,
202+
pageLifetimes: {},
203+
observers: [] as { fields: string; observer: GeneralFuncType }[],
204+
relations: {} as { [key: string]: WechatMiniprogram.Component.RelationOption },
205+
externalClasses: [] as string[],
206+
export: undefined as undefined | (() => TComponentExport),
207+
options: undefined as undefined | WechatMiniprogram.Component.ComponentOptions,
208+
}
209+
210+
private getChainingPolyfillMetadata(
211+
comp: GeneralComponent,
212+
): ChainingPolyfillMetadata | undefined {
213+
return this._$instanceMap.get(comp)
214+
}
215+
216+
private generateChainingPolyfillBehavior() {
217+
const instanceMap = this._$instanceMap
218+
const initData = this._$initData
219+
const getChainingPolyfillMetadata = this.getChainingPolyfillMetadata.bind(this)
220+
return Behavior({
221+
lifetimes: {
222+
created() {
223+
const chainingPolyfillMetadata = new ChainingPolyfillMetadata(initData)
224+
instanceMap.set(this, chainingPolyfillMetadata)
225+
const ctx = chainingPolyfillMetadata.generateBuilderContext(this as any)
226+
initData.initFuncs.call(this, [ctx, chainingPolyfillMetadata])
227+
chainingPolyfillMetadata.setInitDone()
228+
},
229+
},
230+
methods: {
231+
traitBehavior<TOut extends { [x: string]: any }>(
232+
traitBehavior: TraitBehavior<any, TOut>,
233+
): TOut | undefined {
234+
return getChainingPolyfillMetadata(this)!.traitGroup.get(traitBehavior)
235+
},
236+
},
237+
})
238+
}
239+
240+
constructor() {
241+
const getChainingPolyfillMetadata = this.getChainingPolyfillMetadata.bind(this)
242+
243+
// add an early behavior
244+
const beh = this.generateChainingPolyfillBehavior()
245+
this._$definition.behaviors.push(beh)
246+
247+
// init lifetime handlers
248+
this._$definition.lifetimes = {
249249
created() {
250-
getChainingPolyfillMetadata(this).callLifetime(this, 'created')
250+
getChainingPolyfillMetadata(this)!.callLifetime(this, 'created')
251251
},
252252
attached() {
253-
getChainingPolyfillMetadata(this).callLifetime(this, 'attached')
253+
getChainingPolyfillMetadata(this)!.callLifetime(this, 'attached')
254254
},
255255
moved() {
256-
getChainingPolyfillMetadata(this).callLifetime(this, 'moved')
256+
getChainingPolyfillMetadata(this)!.callLifetime(this, 'moved')
257257
},
258258
detached() {
259-
getChainingPolyfillMetadata(this).callLifetime(this, 'detached')
259+
getChainingPolyfillMetadata(this)!.callLifetime(this, 'detached')
260260
},
261261
ready() {
262-
getChainingPolyfillMetadata(this).callLifetime(this, 'ready')
262+
getChainingPolyfillMetadata(this)!.callLifetime(this, 'ready')
263263
},
264-
},
265-
pageLifetimes: {
264+
}
265+
this._$definition.pageLifetimes = {
266266
show() {
267-
getChainingPolyfillMetadata(this).callPageLifetime(this, 'show')
267+
getChainingPolyfillMetadata(this)!.callPageLifetime(this, 'show')
268268
},
269269
hide() {
270-
getChainingPolyfillMetadata(this).callPageLifetime(this, 'hide')
270+
getChainingPolyfillMetadata(this)!.callPageLifetime(this, 'hide')
271271
},
272272
resize(size: unknown) {
273-
getChainingPolyfillMetadata(this).callPageLifetime(this, 'resize', size)
273+
getChainingPolyfillMetadata(this)!.callPageLifetime(this, 'resize', size)
274274
},
275-
},
276-
observers: [] as { fields: string; observer: GeneralFuncType }[],
277-
relations: {} as { [key: string]: WechatMiniprogram.Component.RelationOption },
278-
externalClasses: [] as string[],
279-
export: undefined as undefined | (() => TComponentExport),
280-
options: undefined as undefined | WechatMiniprogram.Component.ComponentOptions,
281-
}
275+
}
282276

283-
constructor() {
284277
// make observer '**' automatically available
285278
this.observer('**', () => {})
286279
}
@@ -307,7 +300,9 @@ export class BaseBehaviorBuilder<
307300
TExtraThisFields
308301
>
309302
> {
310-
if (!this._$definition.export) this._$definition.behaviors.unshift('wx://component-export')
303+
if (!this._$definition.export && isMiniProgramEnvironment()) {
304+
this._$definition.behaviors.unshift('wx://component-export')
305+
}
311306
this._$definition.export = f as any
312307
return this as any
313308
}
@@ -398,18 +393,22 @@ export class BaseBehaviorBuilder<
398393
paths: string | readonly string[],
399394
func: (this: Component<TData, TProperty, TMethod, TExtraThisFields>, ...args: any[]) => any,
400395
): ResolveBehaviorBuilder<this> {
396+
const getChainingPolyfillMetadata = this.getChainingPolyfillMetadata.bind(this)
401397
const fields = typeof paths === 'string' ? paths : paths.join(', ')
402-
const assistObservers = new FuncArr()
403-
assistObservers.add(func)
404-
const observer = function (
405-
this: Component<TData, TProperty, TMethod, TExtraThisFields>,
406-
...args: any[]
407-
) {
408-
assistObservers.call(this, args)
409-
}
410-
this._$definition.observers.push({ fields, observer })
411398
const observers = this._$initData.observers
412-
observers[fields] = assistObservers
399+
if (!observers[fields]) {
400+
observers[fields] = new FuncArr()
401+
const observer = function (
402+
this: Component<TData, TProperty, TMethod, TExtraThisFields>,
403+
...args: any[]
404+
) {
405+
const assistObservers = getChainingPolyfillMetadata(this)!.observers[fields]
406+
assistObservers.call(this, args)
407+
}
408+
this._$definition.observers.push({ fields, observer })
409+
}
410+
const assistObservers = observers[fields]
411+
assistObservers.add(func)
413412
return this as any
414413
}
415414

@@ -537,7 +536,7 @@ export class BaseBehaviorBuilder<
537536
pageLifetimes: rawPageLifetimes,
538537
relations: rawRelations,
539538
externalClasses,
540-
export: exports,
539+
export: exported,
541540
} = definition
542541
if (behaviors) {
543542
this._$definition.behaviors.push(...(behaviors as any[]))
@@ -584,7 +583,7 @@ export class BaseBehaviorBuilder<
584583
Object.assign(this._$definition.relations, rawRelations)
585584
}
586585
if (externalClasses) this.externalClasses(externalClasses)
587-
if (exports) this.export(exports)
586+
if (exported) this.export(exported)
588587
return this as any
589588
}
590589
}

src/index.ts

+7
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,10 @@ import 'miniprogram-api-typings'
22

33
export { ComponentWithPolyfill as Component } from './component'
44
export { BehaviorWithPolyfill as Behavior } from './behavior'
5+
6+
export const isMiniProgramEnvironment = () => {
7+
if (typeof wx !== 'undefined' && typeof wx.getSystemSetting !== 'undefined') {
8+
return true
9+
}
10+
return false
11+
}

test/init_func.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ describe('chaining calls', () => {
3636
)
3737
expect(innerHTML(component)).toBe('<div>246</div>')
3838
})
39+
3940
test('`method` in init function', () => {
4041
const component = renderComponent(
4142
undefined,

test/setup.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,19 @@ const compileTemplate = (src: string) => {
66
group.addTmpl('', src)
77
const genObjectSrc = `return ${group.getTmplGenObjectGroups()}`
88
group.free()
9-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
109
const genObjectGroupList = new Function(genObjectSrc)() as {
1110
[key: string]: any
1211
}
1312
return {
1413
groupList: genObjectGroupList,
15-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
1614
content: genObjectGroupList[''],
1715
}
1816
}
1917

2018
const setup = () => {
2119
const env = new adapter.MiniProgramEnv()
2220
const codeSpace = env.createCodeSpace('', true)
21+
codeSpace.getComponentSpace().updateComponentOptions({ useMethodCallerListeners: true })
2322
const backend = env.associateBackend()
2423
codeSpace.componentEnv('', (env) => {
2524
;(globalThis as any).Behavior = env.Behavior

0 commit comments

Comments
 (0)