glass-easel-miniprogram-adapter 0.1.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.
Files changed (50) hide show
  1. package/README.md +49 -0
  2. package/dist/glass_easel_miniprogram_adapter.d.ts +1 -0
  3. package/dist/glass_easel_miniprogram_adapter.js +2 -0
  4. package/dist/glass_easel_miniprogram_adapter.js.map +1 -0
  5. package/dist/types/src/backend.d.ts +51 -0
  6. package/dist/types/src/backend.d.ts.map +1 -0
  7. package/dist/types/src/behavior.d.ts +35 -0
  8. package/dist/types/src/behavior.d.ts.map +1 -0
  9. package/dist/types/src/component.d.ts +160 -0
  10. package/dist/types/src/component.d.ts.map +1 -0
  11. package/dist/types/src/index.d.ts +58 -0
  12. package/dist/types/src/index.d.ts.map +1 -0
  13. package/dist/types/src/selector_query.d.ts +98 -0
  14. package/dist/types/src/selector_query.d.ts.map +1 -0
  15. package/dist/types/src/space.d.ts +369 -0
  16. package/dist/types/src/space.d.ts.map +1 -0
  17. package/dist/types/src/types.d.ts +77 -0
  18. package/dist/types/src/types.d.ts.map +1 -0
  19. package/dist/types/src/utils.d.ts +2 -0
  20. package/dist/types/src/utils.d.ts.map +1 -0
  21. package/dist/types/tests/base/env.d.ts +3 -0
  22. package/dist/types/tests/base/env.d.ts.map +1 -0
  23. package/dist/types/tests/data_update.test.d.ts +2 -0
  24. package/dist/types/tests/data_update.test.d.ts.map +1 -0
  25. package/dist/types/tests/env.test.d.ts +2 -0
  26. package/dist/types/tests/env.test.d.ts.map +1 -0
  27. package/dist/types/tests/selector.test.d.ts +2 -0
  28. package/dist/types/tests/selector.test.d.ts.map +1 -0
  29. package/dist/types/tests/space.test.d.ts +2 -0
  30. package/dist/types/tests/space.test.d.ts.map +1 -0
  31. package/dist/types/tests/trait_behavior.test.d.ts +2 -0
  32. package/dist/types/tests/trait_behavior.test.d.ts.map +1 -0
  33. package/jest.config.js +13 -0
  34. package/package.json +32 -0
  35. package/src/backend.ts +106 -0
  36. package/src/behavior.ts +101 -0
  37. package/src/component.ts +476 -0
  38. package/src/index.ts +82 -0
  39. package/src/selector_query.ts +356 -0
  40. package/src/space.ts +1514 -0
  41. package/src/types.ts +85 -0
  42. package/src/utils.ts +3 -0
  43. package/tests/base/env.ts +20 -0
  44. package/tests/data_update.test.ts +92 -0
  45. package/tests/env.test.ts +141 -0
  46. package/tests/selector.test.ts +407 -0
  47. package/tests/space.test.ts +953 -0
  48. package/tests/trait_behavior.test.ts +141 -0
  49. package/tsconfig.json +11 -0
  50. package/webpack.config.js +78 -0
package/src/types.ts ADDED
@@ -0,0 +1,85 @@
1
+ import { DeepCopyKind, typeUtils as utils } from 'glass-easel'
2
+ import type { DefinitionFilter, GeneralBehavior, Behavior } from './behavior'
3
+
4
+ export { typeUtils as utils } from 'glass-easel'
5
+
6
+ export const enum StyleIsolation {
7
+ Isolated = 'isolated',
8
+ ApplyShared = 'apply-shared',
9
+ Shared = 'shared',
10
+ PageIsolated = 'page-isolated',
11
+ PageApplyShared = 'page-apply-shared',
12
+ PageShared = 'page-shared',
13
+ }
14
+
15
+ export type ComponentStaticConfig = {
16
+ component?: boolean
17
+ usingComponents?: { [name: string]: string }
18
+ generics?: {
19
+ [name: string]: true | { default?: string }
20
+ }
21
+ placeholder?: { [name: string]: string }
22
+ styleIsolation?: StyleIsolation,
23
+ /** @obsolete */
24
+ addGlobalClass?: boolean,
25
+ pureDataPattern?: string,
26
+ }
27
+
28
+ export type ComponentDefinitionOptions = {
29
+ multipleSlots?: boolean
30
+ pureDataPattern?: RegExp,
31
+ virtualHost?: boolean,
32
+ dataDeepCopy?: DeepCopyKind,
33
+ propertyPassingDeepCopy?: DeepCopyKind,
34
+ propertyEarlyInit?: boolean,
35
+ }
36
+
37
+ type ComponentMethod = utils.ComponentMethod
38
+
39
+ export type BehaviorDefinition<
40
+ TData extends utils.DataList,
41
+ TProperty extends utils.PropertyList,
42
+ TMethod extends utils.MethodList,
43
+ > = {
44
+ behaviors?: Behavior<any, any, any, any>[],
45
+ properties?: TProperty,
46
+ data?: TData | (() => TData),
47
+ observers?:
48
+ ({
49
+ fields?: string,
50
+ observer: ComponentMethod,
51
+ })[]
52
+ | { [fields: string]: ComponentMethod }
53
+ methods?: TMethod,
54
+ created?: ComponentMethod,
55
+ attached?: ComponentMethod,
56
+ ready?: ComponentMethod,
57
+ moved?: ComponentMethod,
58
+ detached?: ComponentMethod,
59
+ lifetimes?: { [name: string]: ComponentMethod },
60
+ pageLifetimes?: { [name: string]: ComponentMethod },
61
+ relations?: utils.RelationParamsWithKey,
62
+ externalClasses?: string[],
63
+ definitionFilter?: DefinitionFilter,
64
+ }
65
+
66
+ export type ComponentDefinition<
67
+ TData extends utils.DataList,
68
+ TProperty extends utils.PropertyList,
69
+ TMethod extends utils.MethodList,
70
+ TComponentExport,
71
+ > = {
72
+ options?: ComponentDefinitionOptions,
73
+ export?: () => TComponentExport,
74
+ } & BehaviorDefinition<TData, TProperty, TMethod>
75
+
76
+ export type GeneralComponentDefinition = ComponentDefinition<any, any, any, any>
77
+
78
+ export type PageDefinition<
79
+ TData extends utils.DataList,
80
+ TExtraFields extends { [k: PropertyKey]: any },
81
+ > = TExtraFields & {
82
+ options?: ComponentDefinitionOptions,
83
+ behaviors?: GeneralBehavior[],
84
+ data?: TData,
85
+ }
package/src/utils.ts ADDED
@@ -0,0 +1,3 @@
1
+ export const guid = (): string => Math.floor((1 + Math.random()) * 0x100000000)
2
+ .toString(16)
3
+ .slice(1)
@@ -0,0 +1,20 @@
1
+ /* eslint-disable no-new-func */
2
+ /* eslint-disable @typescript-eslint/no-implied-eval */
3
+
4
+ import * as glassEasel from 'glass-easel'
5
+ import { TmplGroup } from 'glass-easel-template-compiler'
6
+
7
+ export const tmpl = (src: string): glassEasel.template.ComponentTemplate => {
8
+ const group = new TmplGroup()
9
+ group.addTmpl('', src)
10
+ const genObjectSrc = `return ${group.getTmplGenObjectGroups()}`
11
+ group.free()
12
+ // console.info(genObjectSrc)
13
+ const genObjectGroupList = (new Function(genObjectSrc))() as
14
+ { [key: string]: any }
15
+ return {
16
+ groupList: genObjectGroupList,
17
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
18
+ content: genObjectGroupList['']!,
19
+ }
20
+ }
@@ -0,0 +1,92 @@
1
+ import * as glassEasel from 'glass-easel'
2
+ import { tmpl } from './base/env'
3
+ import {
4
+ MiniProgramEnv,
5
+ } from '../src'
6
+
7
+ const domHtml = (elem: glassEasel.Element): string => {
8
+ const domElem = elem.getBackendElement() as unknown as Element
9
+ return domElem.innerHTML
10
+ }
11
+
12
+ describe('data update', () => {
13
+ test('various data update', () => {
14
+ const env = new MiniProgramEnv()
15
+ const codeSpace = env.createCodeSpace('', true)
16
+
17
+ codeSpace.addComponentStaticConfig('path/to/comp', {})
18
+ codeSpace.addCompiledTemplate('path/to/comp', tmpl(`
19
+ <div wx:for="{{arr}}">{{item}}</div>
20
+ <span>{{obj.sub}}</span>
21
+ `))
22
+ codeSpace.componentEnv('path/to/comp', ({ Component }) => {
23
+ Component()
24
+ .data(() => ({
25
+ arr: [1, 2, 3],
26
+ obj: {
27
+ sub: false,
28
+ },
29
+ }))
30
+ .lifetime('attached', function () {
31
+ this.groupUpdates(() => {
32
+ this.spliceArrayDataOnPath(['arr'], 1, 1, [4, 5])
33
+ this.replaceDataOnPath(['obj', 'sub'], true)
34
+ })
35
+ // eslint-disable-next-line no-use-before-define
36
+ expect(domHtml(root.getComponent()))
37
+ .toBe('<div>1</div><div>4</div><div>5</div><div>3</div><span>true</span>')
38
+ this.groupSetData(() => {
39
+ this.updateData({
40
+ arr: [123],
41
+ })
42
+ })
43
+ // eslint-disable-next-line no-use-before-define
44
+ expect(domHtml(root.getComponent()))
45
+ .toBe('<div>1</div><div>4</div><div>5</div><div>3</div><span>true</span>')
46
+ this.applyDataUpdates()
47
+ // eslint-disable-next-line no-use-before-define
48
+ expect(domHtml(root.getComponent()))
49
+ .toBe('<div>123</div><span>true</span>')
50
+ })
51
+ .register()
52
+ })
53
+
54
+ const ab = env.associateBackend()
55
+ const root = ab.createRoot('body', codeSpace, 'path/to/comp')
56
+ glassEasel.Element.pretendAttached(root.getComponent())
57
+ expect(domHtml(root.getComponent())).toBe('<div>123</div><span>true</span>')
58
+ })
59
+
60
+ test('setData callback', () => new Promise((resolve) => {
61
+ const env = new MiniProgramEnv()
62
+ const codeSpace = env.createCodeSpace('', true)
63
+
64
+ codeSpace.addComponentStaticConfig('path/to/comp', {})
65
+ codeSpace.addCompiledTemplate('path/to/comp', tmpl(`
66
+ <span>{{a}}</span>
67
+ `))
68
+ codeSpace.componentEnv('path/to/comp', ({ Component }) => {
69
+ Component()
70
+ .data(() => ({
71
+ a: 123,
72
+ }))
73
+ .init(function ({ setData, lifetime }) {
74
+ lifetime('attached', () => {
75
+ setData({ a: 789 }, () => {
76
+ this.setData({ a: 456 }, () => {
77
+ // eslint-disable-next-line no-use-before-define
78
+ expect(domHtml(root.getComponent())).toBe('<span>456</span>')
79
+ resolve(undefined)
80
+ })
81
+ })
82
+ })
83
+ })
84
+ .register()
85
+ })
86
+
87
+ const ab = env.associateBackend()
88
+ const root = ab.createRoot('body', codeSpace, 'path/to/comp')
89
+ glassEasel.Element.pretendAttached(root.getComponent())
90
+ expect(domHtml(root.getComponent())).toBe('<span>789</span>')
91
+ }))
92
+ })
@@ -0,0 +1,141 @@
1
+ import * as glassEasel from 'glass-easel'
2
+ import { tmpl } from './base/env'
3
+ import {
4
+ MiniProgramEnv,
5
+ } from '../src'
6
+
7
+ const domHtml = (elem: glassEasel.Element): string => {
8
+ const domElem = elem.getBackendElement() as unknown as Element
9
+ return domElem.innerHTML
10
+ }
11
+
12
+ describe('env', () => {
13
+ test('add global components', () => {
14
+ const env = new MiniProgramEnv()
15
+ const globalCodeSpace = env.getGlobalCodeSpace()
16
+ globalCodeSpace.getComponentSpace().define('external')
17
+ .options({
18
+ virtualHost: true,
19
+ })
20
+ .template(tmpl(`
21
+ <span class="inner" />
22
+ `))
23
+ .registerComponent()
24
+ globalCodeSpace.getComponentSpace().exportComponent('external', 'external')
25
+ const codeSpace = env.createCodeSpace('', true)
26
+
27
+ codeSpace.addComponentStaticConfig('path/to/comp', {
28
+ usingComponents: {
29
+ external: 'external',
30
+ },
31
+ })
32
+
33
+ codeSpace.addCompiledTemplate('path/to/comp', tmpl(`
34
+ <div class="outer">
35
+ <external />
36
+ </div>
37
+ `))
38
+
39
+ codeSpace.componentEnv('path/to/comp', ({ Component }) => {
40
+ Component().register()
41
+ })
42
+
43
+ const backend = new glassEasel.domlikeBackend.CurrentWindowBackendContext()
44
+ const ab = env.associateBackend(backend)
45
+ const root = ab.createRoot('body', codeSpace, 'path/to/comp')
46
+ expect(domHtml(root.getComponent())).toBe('<div class="outer"><span class="inner"></span></div>')
47
+ })
48
+
49
+ test('add global components', () => {
50
+ const env = new MiniProgramEnv()
51
+ const globalCodeSpace = env.getGlobalCodeSpace()
52
+ globalCodeSpace.getComponentSpace().define('external')
53
+ .options({
54
+ virtualHost: true,
55
+ })
56
+ .template(tmpl(`
57
+ <span class="inner" />
58
+ `))
59
+ .registerComponent()
60
+ globalCodeSpace.getComponentSpace().exportComponent('external', 'external')
61
+ const codeSpace = env.createCodeSpace('', true)
62
+
63
+ codeSpace.addComponentStaticConfig('path/to/comp', {
64
+ usingComponents: {
65
+ external: 'external',
66
+ },
67
+ })
68
+
69
+ codeSpace.addCompiledTemplate('path/to/comp', tmpl(`
70
+ <div class="outer">
71
+ <external />
72
+ </div>
73
+ `))
74
+
75
+ codeSpace.componentEnv('path/to/comp', ({ Component }) => {
76
+ Component().register()
77
+ })
78
+
79
+ const backend = new glassEasel.domlikeBackend.CurrentWindowBackendContext()
80
+ const ab = env.associateBackend(backend)
81
+ const root = ab.createRoot('body', codeSpace, 'path/to/comp')
82
+ expect(domHtml(root.getComponent())).toBe('<div class="outer"><span class="inner"></span></div>')
83
+ })
84
+
85
+ test('multiple code spaces', () => {
86
+ const env = new MiniProgramEnv()
87
+ const codeSpace = env.createCodeSpace('', true)
88
+ const pluginCodeSpace1 = env.createCodeSpace('plugin-1-id', false, {
89
+ 'outer-comp-1': 'inner-comp-1',
90
+ 'outer-comp-11': 'inner-comp-1',
91
+ })
92
+ const pluginCodeSpace2 = env.createCodeSpace('plugin-2-id', false, {
93
+ 'outer-comp-2': 'inner-comp-2',
94
+ })
95
+ expect(env.getCodeSpace('plugin-1-id')).toBe(pluginCodeSpace1)
96
+ expect(env.getCodeSpace('plugin-2-id')).toBe(pluginCodeSpace2)
97
+ expect(pluginCodeSpace1.isMainSpace()).toBe(false)
98
+ codeSpace.importCodeSpace('plugin-1-id', 'plugin-1')
99
+ codeSpace.importCodeSpace('plugin-2-id', undefined, true)
100
+ expect(codeSpace.isMainSpace()).toBe(true)
101
+
102
+ pluginCodeSpace1.addCompiledTemplate('inner-comp-1', tmpl('A'))
103
+ pluginCodeSpace1.componentEnv('inner-comp-1', ({ Component }) => {
104
+ Component().register()
105
+ })
106
+
107
+ pluginCodeSpace2.addCompiledTemplate('inner-comp-2', tmpl('B'))
108
+ pluginCodeSpace2.componentEnv('inner-comp-2', ({ Component }) => {
109
+ Component().register()
110
+ })
111
+
112
+ codeSpace.addComponentStaticConfig('path/to/comp', {
113
+ usingComponents: {
114
+ 'c-a': 'plugin://plugin-1/outer-comp-1',
115
+ 'c-aa': 'plugin://plugin-1/outer-comp-11',
116
+ 'i-a': 'plugin-private://plugin-1-id/inner-comp-1',
117
+ 'i-b': 'plugin://plugin-2/outer-comp-2',
118
+ 'c-b': 'plugin-private://plugin-2-id/inner-comp-2',
119
+ },
120
+ })
121
+ codeSpace.addCompiledTemplate('path/to/comp', tmpl(`
122
+ <c-a />
123
+ <c-aa />
124
+ <i-a />
125
+ <i-b />
126
+ <c-b />
127
+ `))
128
+ codeSpace.componentEnv('path/to/comp', ({ Component }) => {
129
+ Component().register()
130
+ })
131
+
132
+ codeSpace.componentEnv('', ({ Component }) => {
133
+ Component().register()
134
+ })
135
+
136
+ const backend = new glassEasel.domlikeBackend.CurrentWindowBackendContext()
137
+ const ab = env.associateBackend(backend)
138
+ const root = ab.createRoot('body', codeSpace, 'path/to/comp')
139
+ expect(domHtml(root.getComponent())).toBe('<c-a>A</c-a><c-aa>A</c-aa><i-a></i-a><i-b></i-b><c-b>B</c-b>')
140
+ })
141
+ })