@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 CHANGED
@@ -1,15 +1,18 @@
1
1
  const App = require('./lib/App.js')
2
- App.app = () => {
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
- App.utils = require('./lib/utils.js')
10
- App.validation = require('./lib/utils/validation.js')
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[definition.name]
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 SessionApiServer({ ...config, app: this })
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
@@ -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
  }
@@ -1,14 +1,16 @@
1
- const ReactiveDao = require("@live-change/dao")
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.reactiveServer = new ReactiveDao.ReactiveServer(
11
- (credentials, connection) => {
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.authentication) {
30
- let auth = Array.isArray(this.config.authentication)
31
- ? this.config.authentication : [this.config.authentication]
32
- for(let authenticator of auth) {
33
- if(authenticator) await authenticator(credentials, this.config)
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
- return new Dao(this.config, { ...credentials })
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)
@@ -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,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/framework",
3
- "version": "0.5.8",
3
+ "version": "0.5.9",
4
4
  "description": "Live Change Framework - ultimate solution for real time mobile/web apps",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -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