@live-change/framework 0.5.8 → 0.5.9
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/index.js +7 -4
- package/lib/App.js +16 -6
- package/lib/runtime/Action.js +1 -1
- package/lib/runtime/ApiServer.js +25 -11
- package/lib/runtime/LiveDao.js +103 -0
- package/lib/utils/CommandQueue.js +1 -1
- package/lib/utils/validation.js +1 -1
- package/package.json +1 -1
- package/lib/runtime/SessionApiServer.js +0 -54
package/index.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
const App = require('./lib/App.js')
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
module.exports = App
|
|
4
|
+
|
|
5
|
+
module.exports.app = () => {
|
|
3
6
|
if(!global.liveChangeFrameworkApp) {
|
|
4
7
|
global.liveChangeFrameworkApp = new App()
|
|
5
8
|
}
|
|
6
9
|
return global.liveChangeFrameworkApp
|
|
7
10
|
}
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
module.exports.utils = require('./lib/utils.js')
|
|
13
|
+
module.exports.validation = require('./lib/utils/validation.js')
|
|
14
|
+
module.exports.rangeProperties = module.exports.utils.rangeProperties
|
|
11
15
|
|
|
12
|
-
module.exports = App
|
|
13
16
|
|
|
14
17
|
module.exports.ActionDefinition = require('./lib/definition/ActionDefinition.js')
|
|
15
18
|
module.exports.EventDefinition = require('./lib/definition/EventDefinition.js')
|
package/lib/App.js
CHANGED
|
@@ -9,8 +9,9 @@ const Service = require("./runtime/Service.js")
|
|
|
9
9
|
const profileLog = require("./utils/profileLog.js")
|
|
10
10
|
|
|
11
11
|
const Dao = require("./runtime/Dao.js")
|
|
12
|
+
const SessionDao = require("./runtime/SessionDao.js")
|
|
13
|
+
const LiveDao = require("./runtime/LiveDao.js")
|
|
12
14
|
const ApiServer = require("./runtime/ApiServer.js")
|
|
13
|
-
const SessionApiServer = require("./runtime/SessionApiServer.js")
|
|
14
15
|
|
|
15
16
|
const reverseRelationProcessor = require("./processors/reverseRelation.js")
|
|
16
17
|
const indexListProcessor = require("./processors/indexList.js")
|
|
@@ -73,10 +74,13 @@ class App {
|
|
|
73
74
|
|
|
74
75
|
this.instanceId = randomString(4)
|
|
75
76
|
this.uidGenerator = uidGenerator(this.instanceId)
|
|
77
|
+
|
|
78
|
+
this.activeTimeouts = new Set()
|
|
76
79
|
}
|
|
77
80
|
|
|
78
81
|
createServiceDefinition( definition ) {
|
|
79
|
-
const config = this.config && this.config.services && this.config.services
|
|
82
|
+
const config = this.config && this.config.services && this.config.services.find
|
|
83
|
+
&& this.config.services.find(c => c.name == definition.name)
|
|
80
84
|
return new ServiceDefinition({ ...definition, config })
|
|
81
85
|
}
|
|
82
86
|
|
|
@@ -150,9 +154,11 @@ class App {
|
|
|
150
154
|
async createApiServer( config ) {
|
|
151
155
|
return new ApiServer({ ...config, app: this })
|
|
152
156
|
}
|
|
153
|
-
|
|
154
157
|
async createSessionApiServer( config ) {
|
|
155
|
-
return new
|
|
158
|
+
return new ApiServer({ ...config, app: this }, SessionDao)
|
|
159
|
+
}
|
|
160
|
+
async createLiveApiServer( config ) {
|
|
161
|
+
return new ApiServer({ ...config, app: this }, LiveDao)
|
|
156
162
|
}
|
|
157
163
|
|
|
158
164
|
generateUid() {
|
|
@@ -253,9 +259,11 @@ class App {
|
|
|
253
259
|
requestTimeout = this.requestTimeout
|
|
254
260
|
}
|
|
255
261
|
if(requestTimeout) {
|
|
256
|
-
setTimeout(() => {
|
|
262
|
+
const timeout = setTimeout(() => {
|
|
263
|
+
this.activeTimeouts.delete(timeout)
|
|
257
264
|
reject('timeout')
|
|
258
265
|
}, requestTimeout)
|
|
266
|
+
this.activeTimeouts.add(timeout)
|
|
259
267
|
}
|
|
260
268
|
}).finally(() => {
|
|
261
269
|
objectObservable.unobserve(observer)
|
|
@@ -379,6 +387,9 @@ class App {
|
|
|
379
387
|
}
|
|
380
388
|
|
|
381
389
|
async close() {
|
|
390
|
+
for(const timeout of this.activeTimeouts) {
|
|
391
|
+
clearTimeout(timeout)
|
|
392
|
+
}
|
|
382
393
|
this.dao.dispose()
|
|
383
394
|
}
|
|
384
395
|
|
|
@@ -386,4 +397,3 @@ class App {
|
|
|
386
397
|
|
|
387
398
|
|
|
388
399
|
module.exports = App
|
|
389
|
-
module.exports.rangeProperties = utils.rangeProperties
|
package/lib/runtime/Action.js
CHANGED
|
@@ -42,7 +42,7 @@ class Action {
|
|
|
42
42
|
parameters: await preFilterParameters(parameters, this.definition.properties)
|
|
43
43
|
}
|
|
44
44
|
if(parameters._commandId) command.id = parameters._commandId
|
|
45
|
-
console.log("CALL COMMAND", JSON.stringify(command, null, " "))
|
|
45
|
+
//console.log("CALL COMMAND", JSON.stringify(command, null, " "))
|
|
46
46
|
return this.service.app.command(command, this.definition.requestTimeout)
|
|
47
47
|
}
|
|
48
48
|
}
|
package/lib/runtime/ApiServer.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
const
|
|
1
|
+
const LcDao = require("@live-change/dao")
|
|
2
2
|
const Dao = require("./Dao.js")
|
|
3
3
|
const cookie = require('cookie')
|
|
4
4
|
|
|
5
5
|
const { getIp } = require("./utils.js")
|
|
6
6
|
|
|
7
7
|
class ApiServer {
|
|
8
|
-
constructor(config) {
|
|
8
|
+
constructor(config, DaoConstructor = Dao) {
|
|
9
9
|
this.config = config
|
|
10
|
-
this.
|
|
11
|
-
|
|
10
|
+
this.DaoConstructor = DaoConstructor
|
|
11
|
+
|
|
12
|
+
this.reactiveServer = new LcDao.ReactiveServer(
|
|
13
|
+
(credentials, connection) => {
|
|
12
14
|
const ip = getIp(connection)
|
|
13
15
|
if(this.config.fastAuth) {
|
|
14
16
|
if(typeof this.config.fastAuth == 'function') {
|
|
@@ -24,16 +26,28 @@ class ApiServer {
|
|
|
24
26
|
}, config)
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
async daoFactory(credentialsp, ip)
|
|
29
|
+
async daoFactory(credentialsp, ip) {
|
|
28
30
|
let credentials = { ...credentialsp, ip, roles: [] }
|
|
29
|
-
if(this.config.
|
|
30
|
-
|
|
31
|
-
? this.config.
|
|
32
|
-
for(
|
|
33
|
-
if(authenticator
|
|
31
|
+
if(this.config.authenticators) {
|
|
32
|
+
const auth = Array.isArray(this.config.authenticators)
|
|
33
|
+
? this.config.authenticators : [this.config.authenticators]
|
|
34
|
+
for(const authenticator of auth) {
|
|
35
|
+
if(authenticator && authenticator.prepareCredentials)
|
|
36
|
+
await authenticator.prepareCredentials(credentials, this.config)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
for(const service of this.config.services) {
|
|
40
|
+
console.log("SERIVCE AUTH", service.name, service.authenticators)
|
|
41
|
+
if(service.authenticators) {
|
|
42
|
+
for(const authenticator of service.authenticators) {
|
|
43
|
+
if(authenticator && authenticator.prepareCredentials)
|
|
44
|
+
await authenticator.prepareCredentials(credentials, this.config)
|
|
45
|
+
}
|
|
34
46
|
}
|
|
35
47
|
}
|
|
36
|
-
|
|
48
|
+
const dao = new this.DaoConstructor(this.config, { ...credentials })
|
|
49
|
+
await dao.start()
|
|
50
|
+
return dao
|
|
37
51
|
}
|
|
38
52
|
|
|
39
53
|
handleConnection(connection) {
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
const LcDao = require("@live-change/dao")
|
|
2
|
+
const Dao = require("./Dao.js")
|
|
3
|
+
|
|
4
|
+
const { waitForSignal } = require('./utils.js')
|
|
5
|
+
|
|
6
|
+
class LiveDao extends LcDao.DaoProxy {
|
|
7
|
+
constructor(config, credentials) {
|
|
8
|
+
super(null)
|
|
9
|
+
this.config = config
|
|
10
|
+
this.initialCredentials = credentials
|
|
11
|
+
|
|
12
|
+
this.authenticators = []
|
|
13
|
+
if(this.config.authenticators) {
|
|
14
|
+
const auth = Array.isArray(this.config.authenticators)
|
|
15
|
+
? this.config.authenticators : [this.config.authenticators]
|
|
16
|
+
for(const authenticator of auth) {
|
|
17
|
+
if(authenticator && authenticator.authenticatorObservable)
|
|
18
|
+
this.authenticators.push(authenticator)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
for(const service of this.config.services) {
|
|
22
|
+
console.log("SERIVCE AUTH", service.name, service.authenticators)
|
|
23
|
+
if(service.authenticators) {
|
|
24
|
+
for(const authenticator of service.authenticators) {
|
|
25
|
+
if(authenticator && authenticator.authenticatorObservable)
|
|
26
|
+
this.authenticators.push(authenticator)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
this.currentDao = null
|
|
32
|
+
this.disposed = false
|
|
33
|
+
this.started = false
|
|
34
|
+
this.credentials = JSON.parse(JSON.stringify(this.initialCredentials))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async refreshCredentials() {
|
|
38
|
+
if(!this.started) return /// waiting for start
|
|
39
|
+
const newCredentials = this.computeCredentials()
|
|
40
|
+
if(JSON.stringify(newCredentials) != JSON.stringify(this.credentials)) {
|
|
41
|
+
this.credentials = newCredentials
|
|
42
|
+
this.buildDao()
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
computeCredentials() {
|
|
47
|
+
let credentials = JSON.parse(JSON.stringify(this.initialCredentials))
|
|
48
|
+
for(const credentialsObserver of this.credentialsObservations) {
|
|
49
|
+
credentials = {
|
|
50
|
+
...credentials,
|
|
51
|
+
...credentialsObservers.credentials,
|
|
52
|
+
roles: [...credentials.roles, ...credentialsObserver.credentials.roles]
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return credentials
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async start() {
|
|
59
|
+
this.credentialsObservations = this.authenticators.map(authenticator => {
|
|
60
|
+
const observable = authenticator.authenticatorObservable(this.initialCredentials)
|
|
61
|
+
const observer = {
|
|
62
|
+
set: (newCredentials) => {
|
|
63
|
+
state.credentials = newCredentials
|
|
64
|
+
this.refreshCredentials()
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const promise = waitForSignal(observable)
|
|
68
|
+
const state = {
|
|
69
|
+
observable, observer, promise, credentials: {}
|
|
70
|
+
}
|
|
71
|
+
return state
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
await Promise.all(this.credentialsObservations.map(observation => observation.promise))
|
|
75
|
+
|
|
76
|
+
const newCredentials = this.computeCredentials()
|
|
77
|
+
if(JSON.stringify(newCredentials) != JSON.stringify(this.credentials)) {
|
|
78
|
+
this.credentials = newCredentials
|
|
79
|
+
}
|
|
80
|
+
this.buildDao()
|
|
81
|
+
this.started = true
|
|
82
|
+
|
|
83
|
+
if(!this.dao) throw new Error("dao not created?!")
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
buildDao() {
|
|
87
|
+
const oldDao = this.currentDao
|
|
88
|
+
this.currentDao = new Dao(this.config, { ...this.credentials })
|
|
89
|
+
this.setDao(this.currentDao)
|
|
90
|
+
if(oldDao) oldDao.dispose()
|
|
91
|
+
}
|
|
92
|
+
dispose() {
|
|
93
|
+
if(this.disposed) throw new Error("DAO dispose called twice!")
|
|
94
|
+
this.disposed = true
|
|
95
|
+
this.started = false
|
|
96
|
+
for(const observation of this.credentialsObservations) {
|
|
97
|
+
observation.observable.unobserver(observation.observer)
|
|
98
|
+
}
|
|
99
|
+
super.dispose()
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
module.exports = LiveDao
|
|
@@ -48,7 +48,7 @@ class CommandQueue {
|
|
|
48
48
|
})
|
|
49
49
|
}
|
|
50
50
|
async handleCommand(command) {
|
|
51
|
-
console.log("COMMNAD HANDLE!", command)
|
|
51
|
+
//console.log("COMMNAD HANDLE!", command)
|
|
52
52
|
if(command.state != 'new') return
|
|
53
53
|
if(this.commandsStarted.has(command.id)) return
|
|
54
54
|
this.commandsStarted.set(command.id, command)
|
package/lib/utils/validation.js
CHANGED
|
@@ -28,7 +28,7 @@ function getValidators(source, service) {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
async function validate(props, validators, context) {
|
|
31
|
-
console.log("VALIDATE PROPS", props, "WITH", validators)
|
|
31
|
+
//console.log("VALIDATE PROPS", props, "WITH", validators)
|
|
32
32
|
let propPromises = {}
|
|
33
33
|
for(let propName in validators) {
|
|
34
34
|
let propValidators = validators[propName]
|
package/package.json
CHANGED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
const LcDao = require("@live-change/dao")
|
|
2
|
-
const SessionDao = require("./SessionDao.js")
|
|
3
|
-
const cookie = require('cookie')
|
|
4
|
-
|
|
5
|
-
const { getIp } = require("./utils.js")
|
|
6
|
-
|
|
7
|
-
class SessionApiServer {
|
|
8
|
-
constructor(config) {
|
|
9
|
-
this.config = config
|
|
10
|
-
this.reactiveServer = new LcDao.ReactiveServer(
|
|
11
|
-
(credentials, connection) => {
|
|
12
|
-
const ip = getIp(connection)
|
|
13
|
-
if(this.config.fastAuth) {
|
|
14
|
-
if(typeof this.config.fastAuth == 'function') {
|
|
15
|
-
credentials = this.config.fastAuth(connection)
|
|
16
|
-
} else {
|
|
17
|
-
const cookies = cookie.parse(connection.headers.cookie || '')
|
|
18
|
-
const sessionKey = cookies.sessionKey
|
|
19
|
-
if(!sessionKey) throw new Error('session key undefined')
|
|
20
|
-
credentials = { sessionKey }
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return this.daoFactory(credentials, ip)
|
|
24
|
-
}, config)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async daoFactory(credentialsp, ip) {
|
|
28
|
-
let credentials = { ...credentialsp, ip, roles: [] }
|
|
29
|
-
if(this.config.authenticators) {
|
|
30
|
-
const auth = Array.isArray(this.config.authenticators)
|
|
31
|
-
? this.config.authenticators : [this.config.authenticators]
|
|
32
|
-
for(const authenticator of auth) {
|
|
33
|
-
if(authenticator) await authenticator(credentials, this.config)
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
for(const service of this.config.services) {
|
|
37
|
-
console.log("SERIVCE AUTH", service.name, service.authenticators)
|
|
38
|
-
if(service.authenticators) {
|
|
39
|
-
for(const authenticator of service.authenticators) {
|
|
40
|
-
if(authenticator) await authenticator(credentials, this.config)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
const dao = new SessionDao(this.config, { ...credentials })
|
|
45
|
-
await dao.start()
|
|
46
|
-
return dao
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
handleConnection(connection) {
|
|
50
|
-
this.reactiveServer.handleConnection(connection)
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
module.exports = SessionApiServer
|