@@ -4,13 +4,14 @@ import { rootLogger } from '../lib/nexus-logger'
4
4
import * as Plugin from '../lib/plugin'
5
5
import { RuntimeContributions } from '../lib/plugin'
6
6
import * as Reflection from '../lib/reflection/stage'
7
+ import { builtinScalars } from '../lib/scalars'
7
8
import { Index } from '../lib/utils'
9
+ import * as Lifecycle from './lifecycle'
8
10
import * as Schema from './schema'
9
11
import * as Server from './server'
10
12
import { ContextCreator } from './server/server'
11
13
import * as Settings from './settings'
12
14
import { assertAppNotAssembled } from './utils'
13
- import { builtinScalars } from '../lib/scalars'
14
15
15
16
const log = Logger . log . child ( 'app' )
16
17
@@ -33,6 +34,12 @@ export interface App {
33
34
* [API Reference](https://nxs.li/docs/api/settings) ⌁ [Issues](https://nxs.li/issues/components/settings)
34
35
*/
35
36
settings : Settings . Settings
37
+ /**
38
+ * [API Reference](https://nxs.li/docs/api/on) ⌁ [Issues](https://nxs.li/issues/components/lifecycle)
39
+ *
40
+ * Use the lifecycle component to tap into application events.
41
+ */
42
+ on : Lifecycle . Lifecycle
36
43
/**
37
44
* [API Reference](https://nxs.li/docs/api/use-plugins) ⌁ [Issues](https://nxs.li/issues/components/plugins)
38
45
*/
@@ -84,7 +91,10 @@ export type AppState = {
84
91
createContext : ContextCreator
85
92
}
86
93
running : boolean
87
- schemaComponent : Schema . LazyState
94
+ components : {
95
+ schema : Schema . LazyState
96
+ lifecycle : Lifecycle . LazyState
97
+ }
88
98
}
89
99
90
100
export type PrivateApp = App & {
@@ -99,45 +109,71 @@ export type PrivateApp = App & {
99
109
* type says.
100
110
*/
101
111
export function createAppState ( ) : AppState {
102
- const appState = {
112
+ const appState : AppState = {
103
113
assembled : null ,
104
114
running : false ,
105
115
plugins : [ ] ,
106
- } as Omit < AppState , 'schemaComponent' >
116
+ components : { } as any , // populated by components
117
+ }
107
118
108
- return appState as any
119
+ return appState
109
120
}
110
121
111
122
/**
112
123
* Create an app instance
113
124
*/
114
125
export function create ( ) : App {
115
- const appState = createAppState ( )
116
- const serverComponent = Server . create ( appState )
117
- const schemaComponent = Schema . create ( appState )
118
- const settingsComponent = Settings . create ( appState , {
126
+ const state = createAppState ( )
127
+ const serverComponent = Server . create ( state )
128
+ const schemaComponent = Schema . create ( state )
129
+ const settingsComponent = Settings . create ( state , {
119
130
serverSettings : serverComponent . private . settings ,
120
131
schemaSettings : schemaComponent . private . settings ,
121
132
log : Logger . log ,
122
133
} )
134
+ const lifecycleComponent = Lifecycle . create ( state )
123
135
124
136
const app : App = {
125
137
log : log ,
126
138
settings : settingsComponent . public ,
127
139
schema : schemaComponent . public ,
128
140
server : serverComponent . public ,
141
+ on : lifecycleComponent . public ,
129
142
reset ( ) {
130
143
// todo once we have log filtering, make this debug level
131
144
rootLogger . trace ( 'resetting state' )
132
145
schemaComponent . private . reset ( )
133
146
serverComponent . private . reset ( )
134
147
settingsComponent . private . reset ( )
135
- appState . assembled = null
136
- appState . plugins = [ ]
137
- appState . running = false
148
+ lifecycleComponent . private . reset ( )
149
+ state . assembled = null
150
+ state . plugins = [ ]
151
+ state . running = false
152
+ } ,
153
+ async start ( ) {
154
+ if ( Reflection . isReflection ( ) ) return
155
+ if ( state . running ) return
156
+ if ( ! state . assembled ) {
157
+ throw new Error ( 'Must call app.assemble before calling app.start' )
158
+ }
159
+ lifecycleComponent . private . trigger . start ( {
160
+ schema : state . assembled ! . schema ,
161
+ } )
162
+ await serverComponent . private . start ( )
163
+ state . running = true
164
+ } ,
165
+ async stop ( ) {
166
+ if ( Reflection . isReflection ( ) ) return
167
+ if ( ! state . running ) return
168
+ await serverComponent . private . stop ( )
169
+ state . running = false
170
+ } ,
171
+ use ( plugin ) {
172
+ assertAppNotAssembled ( state , 'app.use' , 'The plugin you attempted to use will be ignored' )
173
+ state . plugins . push ( plugin )
138
174
} ,
139
175
assemble ( ) {
140
- if ( appState . assembled ) return
176
+ if ( state . assembled ) return
141
177
142
178
schemaComponent . private . beforeAssembly ( )
143
179
@@ -150,44 +186,25 @@ export function create(): App {
150
186
*/
151
187
if ( Reflection . isReflectionStage ( 'plugin' ) ) return
152
188
153
- appState . assembled = { } as AppState [ 'assembled' ]
189
+ state . assembled = { } as AppState [ 'assembled' ]
154
190
155
- const loadedPlugins = Plugin . importAndLoadRuntimePlugins (
156
- appState . plugins ,
157
- appState . schemaComponent . scalars
158
- )
159
- appState . assembled ! . loadedPlugins = loadedPlugins
191
+ const loadedPlugins = Plugin . importAndLoadRuntimePlugins ( state . plugins , state . components . schema . scalars )
192
+ state . assembled ! . loadedPlugins = loadedPlugins
160
193
161
194
const { schema, missingTypes } = schemaComponent . private . assemble ( loadedPlugins )
162
- appState . assembled ! . schema = schema
163
- appState . assembled ! . missingTypes = missingTypes
195
+ state . assembled ! . schema = schema
196
+ state . assembled ! . missingTypes = missingTypes
164
197
165
198
if ( Reflection . isReflectionStage ( 'typegen' ) ) return
166
199
167
200
const { createContext } = serverComponent . private . assemble ( loadedPlugins , schema )
168
- appState . assembled ! . createContext = createContext
201
+ state . assembled ! . createContext = createContext
169
202
170
203
const { settings } = settingsComponent . private . assemble ( )
171
- appState . assembled ! . settings = settings
204
+ state . assembled ! . settings = settings
172
205
173
206
schemaComponent . private . checks ( )
174
207
} ,
175
- async start ( ) {
176
- if ( Reflection . isReflection ( ) ) return
177
- if ( appState . running ) return
178
- await serverComponent . private . start ( )
179
- appState . running = true
180
- } ,
181
- async stop ( ) {
182
- if ( Reflection . isReflection ( ) ) return
183
- if ( ! appState . running ) return
184
- await serverComponent . private . stop ( )
185
- appState . running = false
186
- } ,
187
- use ( plugin ) {
188
- assertAppNotAssembled ( appState , 'app.use' , 'The plugin you attempted to use will be ignored' )
189
- appState . plugins . push ( plugin )
190
- } ,
191
208
}
192
209
193
210
/**
@@ -209,7 +226,7 @@ export function create(): App {
209
226
return {
210
227
...app ,
211
228
private : {
212
- state : appState ,
229
+ state : state ,
213
230
} ,
214
231
} as App
215
232
}
0 commit comments