forked from cerebral/overmind
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.ts
More file actions
126 lines (106 loc) · 3.78 KB
/
index.ts
File metadata and controls
126 lines (106 loc) · 3.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { EventType, Overmind, TApp, Configuration } from 'overmind'
// @ts-ignore
import { NgZone } from '@angular/core'
import { IMutation } from 'proxy-state-tree'
export type TConnect<Config extends Configuration> = {
state: TApp<Config>['state']
actions: TApp<Config>['actions']
addMutationListener: (cb: (mutation: IMutation) => void) => () => void
}
let nextComponentId = 0
export const createConnect = <A extends Overmind<any>>(overmind: A) => () => {
const componentId = nextComponentId++
let componentInstanceId = 0
return function(target: any) {
const targetNgOnInit = target.prototype.ngOnInit
const targetNgDoCheck = target.prototype.ngDoCheck
const targetNgAfterContentInit = target.prototype.ngAfterContentInit
const targetNgAfterViewInit = target.prototype.ngAfterViewInit
const targetNgAfterViewChecked = target.prototype.ngAfterViewChecked
target.prototype.ngOnInit = function() {
const ngZ = new NgZone({ enableLongStackTrace: false })
this.__tree = (overmind as any).proxyStateTree.getTrackStateTree()
this.__currentFlushId = 0
this.overmind = {
state: this.__tree.state,
actions: overmind.actions,
addMutationListener: overmind.addMutationListener,
}
this.__shouldUpdatePaths = false
this.__componentInstanceId = componentInstanceId++
this.__onUpdate = (mutations, paths, flushId) => {
this.__currentFlushId = flushId
if (this.cdr) {
this.cdr.markForCheck()
}
ngZ.run(() => {})
}
if (targetNgOnInit) {
targetNgOnInit.call(this)
}
if (
!this.cdr &&
(!target['__annotations__'][0] ||
target['__annotations__'][0].changeDetection === 0)
) {
throw new Error(
'overmind-angular ERROR: You have to inject the ChangeDetectionRef as "cdr" on the component. In the constructor, add argument: "private cdr: ChangeDetectorRef" '
)
}
}
target.prototype.ngAfterContentInit = function() {
this.__tree.track(this.__onUpdate)
if (targetNgAfterContentInit) {
targetNgAfterContentInit.call(this)
}
}
target.prototype.ngAfterViewInit = function() {
overmind.eventHub.emitAsync(EventType.COMPONENT_ADD, {
componentId,
componentInstanceId: this.__componentInstanceId,
name: this.constructor.name || '',
paths: Array.from(this.__tree.pathDependencies) as any,
})
if (targetNgAfterViewInit) {
targetNgAfterViewInit.call(this)
}
}
target.prototype.ngDoCheck = function() {
if (this.__shouldUpdatePaths) {
this.__tree.track(this.__onUpdate)
}
if (targetNgDoCheck) {
targetNgDoCheck.call(this)
}
}
target.prototype.ngAfterViewChecked = function() {
if (this.__shouldUpdatePaths) {
this.__shouldUpdatePaths = false
overmind.eventHub.emitAsync(EventType.COMPONENT_UPDATE, {
componentId,
componentInstanceId: this.__componentInstanceId,
name: this.constructor.name || '',
paths: Array.from(this.__tree.pathDependencies) as any,
flushId: this.__currentFlushId,
})
}
if (targetNgAfterViewChecked) {
targetNgAfterViewChecked.call(this)
}
}
let targetNgOnDestroy = target.prototype.ngOnDestroy
target.prototype.ngOnDestroy = function() {
overmind.eventHub.emitAsync(EventType.COMPONENT_REMOVE, {
componentId,
componentInstanceId: this.__componentInstanceId,
name: this.constructor.name || '',
})
const anyOvermind = overmind as any
anyOvermind.proxyStateTree.disposeTree(this.__tree)
if (targetNgOnDestroy) {
targetNgOnDestroy.call(this)
}
}
return target
}
}