@live-change/framework
Advanced tools
Comparing version 0.4.7 to 0.4.8
@@ -8,2 +8,4 @@ const ReactiveDao = require("@live-change/dao") | ||
const profileLog = require("./utils/profileLog.js") | ||
const RTCMSDao = require("./runtime/Dao.js") | ||
@@ -13,4 +15,2 @@ const ApiServer = require("./runtime/ApiServer.js") | ||
const utils = require("./utils.js") | ||
const { Client: ElasticSearch } = require('@elastic/elasticsearch') | ||
@@ -37,2 +37,3 @@ | ||
class App { | ||
@@ -89,2 +90,4 @@ | ||
this.profileLog = profileLog | ||
this.databaseName = env.DB_NAME || 'rtapp-test' | ||
@@ -123,3 +126,7 @@ } | ||
async updateService( service, { path, updaters, force } = {}) { | ||
async updateService( service, { updaters, force } = {}) { | ||
const profileOp = await this.profileLog.begin({ | ||
operation: "updateService", serviceName: service.name, force | ||
}) | ||
this.dao.request(['database', 'createTable'], this.databaseName, 'services').catch(e => 'ok') | ||
@@ -137,2 +144,4 @@ let oldServiceJson = await this.dao.get(['database', 'tableObject', this.databaseName, 'services', service.name]) | ||
{ id: service.name , ...service }) | ||
await this.profileLog.end(profileOp) | ||
} | ||
@@ -142,2 +151,5 @@ | ||
console.log("Starting service", serviceDefinition.name, "!") | ||
const profileOp = await this.profileLog.begin({ | ||
operation: "startService", serviceName: serviceDefinition.name, config | ||
}) | ||
if(!(serviceDefinition instanceof ServiceDefinition)) | ||
@@ -148,2 +160,3 @@ serviceDefinition = new ServiceDefinition(serviceDefinition) | ||
console.log("service started", serviceDefinition.name, "!") | ||
await this.profileLog.end(profileOp) | ||
return service | ||
@@ -177,2 +190,5 @@ } | ||
async trigger(data) { | ||
const profileOp = await this.profileLog.begin({ | ||
operation: "callTrigger", triggerType: data.type, id: data.id, by: data.by | ||
}) | ||
const routes = await this.dao.get(['database', 'tableRange', this.databaseName, 'triggerRoutes', | ||
@@ -185,3 +201,5 @@ { gte: data.type+'=', lte: data.type+'=\xFF\xFF\xFF\xFF' }]) | ||
} | ||
const result = await Promise.all(promises) | ||
const promise = Promise.all(promises) | ||
await this.profileLog.endPromise(profileOp, promise) | ||
const result = await promise | ||
console.log("TRIGGER FINISHED!", result) | ||
@@ -192,2 +210,3 @@ return result | ||
async triggerService(service, data) { | ||
if(!data.id) data.id = this.generateUid() | ||
@@ -197,2 +216,7 @@ data.service = service | ||
if(!data.timestamp) data.timestamp = (new Date()).toISOString() | ||
const profileOp = await this.profileLog.begin({ | ||
operation: "callTriggerService", triggerType: data.type, service, triggerId: data.id, by: data.by | ||
}) | ||
const triggersTable = this.splitCommands ? `${this.name}_triggers` : 'triggers' | ||
@@ -207,3 +231,3 @@ const objectObservable = this.dao.observable( | ||
let observer | ||
return new Promise((resolve, reject) => { | ||
const promise = new Promise((resolve, reject) => { | ||
observer = (signal, value) => { | ||
@@ -219,2 +243,4 @@ if(signal != 'set') return reject('unknownSignal') | ||
}) | ||
await this.profileLog.endPromise(profileOp, promise) | ||
return promise | ||
} | ||
@@ -228,2 +254,8 @@ | ||
data.state = 'new' | ||
const profileOp = await this.profileLog.begin({ | ||
operation: "callCommand", commandType: data.type, service: data.service, | ||
commandId: data.id, by: data.by, client: data.client | ||
}) | ||
const commandsTable = this.splitCommands ? `${data.service}_commands` : 'commands' | ||
@@ -238,3 +270,3 @@ const objectObservable = this.dao.observable( | ||
let observer | ||
return new Promise((resolve, reject) => { | ||
const promise = new Promise((resolve, reject) => { | ||
observer = (signal, value) => { | ||
@@ -258,2 +290,6 @@ if(signal != 'set') return reject('unknownSignal') | ||
}) | ||
await this.profileLog.endPromise(profileOp, promise) | ||
return promise | ||
} | ||
@@ -292,3 +328,9 @@ | ||
} | ||
return new Promise((resolve, reject) => { | ||
const [action, id] = reportId.split('_') | ||
const triggerId = action == 'trigger' ? id : undefined | ||
const commandId = action == 'command' ? id : undefined | ||
const profileOp = await this.profileLog.begin({ | ||
operation: "waitForEvents", action: action, commandId, triggerId, reportId, events, timeout | ||
}) | ||
const promise = new Promise((resolve, reject) => { | ||
let done = false | ||
@@ -349,7 +391,11 @@ let finishedEvents = [] | ||
}) | ||
await this.profileLog.endPromise(profileOp, promise) | ||
return promise | ||
} | ||
async assertTime(taskName, duration, task, ...data) { | ||
const profileOp = await this.profileLog.begin({ operation: 'assertTime', taskName }) | ||
const taskTimeout = setTimeout(() => { | ||
console.log(`TASK ${taskName} TIMEOUT`, ...data) | ||
this.profileLog.end({ ...profileOp, result: "timeout" }) | ||
}, duration) | ||
@@ -361,2 +407,3 @@ try { | ||
clearTimeout(taskTimeout) | ||
await this.profileLog.end({ ...profileOp, result: "done" }) | ||
} | ||
@@ -363,0 +410,0 @@ } |
const ReactiveDao = require("@live-change/dao") | ||
const profileLog = require("../utils/profileLog.js") | ||
function promiseMap(promise, fn) { | ||
@@ -39,9 +41,51 @@ if(promise.then) return promise.then(fn) | ||
let view = service.views[viewName] | ||
values[viewName] = { | ||
observable(parameters) { | ||
return view.observable(parameters, clientData) | ||
}, | ||
get(parameters) { | ||
return view.get(parameters, clientData) | ||
if(process.env.PROFILE_READS == "YES") { | ||
values[viewName] = { | ||
async observable(parameters) { | ||
const observable = await view.observable(parameters, clientData) | ||
if(!observable.set) { | ||
console.error("OBSERVABLE WITH NO SET", observable) | ||
} | ||
const oldSet = observable.set.bind(observable) | ||
const oldObserve = observable.observe.bind(observable) | ||
const oldUnobserve = observable.unobserve.bind(observable) | ||
let observableTime = Date.now() | ||
observable.set = (...args) => { | ||
if(args[0] !== undefined) | ||
profileLog.log({ operation: "observeLoaded", | ||
serviceName: service.name, viewName, parameters, client: clientData, | ||
duration: Date.now() - observableTime }) | ||
return oldSet(...args) | ||
} | ||
observable.observe = (...args) => { | ||
observableTime = Date.now() | ||
profileLog.log({ operation: "observe", | ||
serviceName: service.name, viewName, parameters, client: clientData }) | ||
return oldObserve(...args) | ||
} | ||
observable.unobserve = (...args) => { | ||
profileLog.log({ operation: "unobserve", | ||
serviceName: service.name, viewName, parameters, client: clientData, | ||
observationDuration: Date.now() - observableTime }) | ||
return oldUnobserve(...args) | ||
} | ||
return observable | ||
}, | ||
async get(parameters) { | ||
const profileOp = await profileLog.begin({ operation: "get", | ||
serviceName: service.name, viewName, parameters, client: clientData }) | ||
const promise = view.get(parameters, clientData) | ||
await profileLog.endPromise(profileOp, promise) | ||
return promise | ||
} | ||
} | ||
} else { | ||
values[viewName] = { | ||
observable(parameters) { | ||
return view.observable(parameters, clientData) | ||
}, | ||
get(parameters) { | ||
return view.get(parameters, clientData) | ||
} | ||
} | ||
} | ||
@@ -48,0 +92,0 @@ } |
@@ -22,2 +22,4 @@ const Model = require("./Model.js") | ||
this.profileLog = app.profileLog | ||
this.dao = definition.daoFactory ? definition.daoFactory(app) : app.dao | ||
@@ -71,3 +73,2 @@ this.databaseName = app.databaseName | ||
async start(config) { | ||
this.definition._runtime = this | ||
@@ -116,3 +117,9 @@ | ||
this.eventSourcing.addEventHandler(eventName, async (ev, bucket) => { | ||
await event.execute(ev, bucket) | ||
await this.profileLog.profile({ operation: "handleEvent", eventName, id: ev.id, | ||
bucketId: bucket.id, triggerId: bucket.triggerId, commandId: bucket.commandId }, | ||
() => { | ||
console.log("EXECUTING EVENT", ev) | ||
return event.execute(ev, bucket) | ||
} | ||
) | ||
}) | ||
@@ -143,2 +150,4 @@ this.eventSourcing.onBucketEnd = async (bucket, handledEvents) => { | ||
this.commandQueue.addCommandHandler(actionName, async (command) => { | ||
const profileOp = this.profileLog.begin({ operation: 'queueCommand', commandType: actionName, | ||
commandId: command.id, client: command.client }) | ||
const reportFinished = action.definition.waitForEvents ? 'command_'+command.id : undefined | ||
@@ -149,3 +158,25 @@ const flags = { commandId: command.id, reportFinished } | ||
: new SingleEmitQueue(this, flags) | ||
const routine = async () => { | ||
const routine = () => this.profileLog.profile({ operation: 'runCommand', commandType: actionName, | ||
commandId: command.id, client: command.client }, async () => { | ||
const result = await this.app.assertTime('command '+action.definition.name, 10000, | ||
() => action.runCommand(command, (...args) => emit.emit(...args)), command) | ||
const events = await emit.commit() | ||
if(action.definition.waitForEvents) | ||
await this.app.waitForEvents(reportFinished, events, action.definition.waitForEvents) | ||
return result | ||
}) | ||
routine.key = keyFunction(command) | ||
const promise = this.keyBasedCommandQueues.queue(routine) | ||
await this.profileLog.endPromise(profileOp, promise) | ||
return promise | ||
}) | ||
} else { | ||
this.commandQueue.addCommandHandler(actionName, | ||
(command) => this.profileLog.profile({ operation: 'runCommand', commandType: actionName, | ||
commandId: command.id, client: command.client }, async () => { | ||
const reportFinished = action.definition.waitForEvents ? 'command_'+command.id : undefined | ||
const flags = { commandId: command.id, reportFinished } | ||
const emit = this.app.splitEvents | ||
? new SplitEmitQueue(this, flags) | ||
: new SingleEmitQueue(this, flags) | ||
const result = await this.app.assertTime('command '+action.definition.name, 10000, | ||
@@ -157,20 +188,5 @@ () => action.runCommand(command, (...args) => emit.emit(...args)), command) | ||
return result | ||
} | ||
routine.key = keyFunction(command) | ||
return this.keyBasedCommandQueues.queue(routine) | ||
}) | ||
} else { | ||
this.commandQueue.addCommandHandler(actionName, async (command) => { | ||
const reportFinished = action.definition.waitForEvents ? 'command_'+command.id : undefined | ||
const flags = { commandId: command.id, reportFinished } | ||
const emit = this.app.splitEvents | ||
? new SplitEmitQueue(this, flags) | ||
: new SingleEmitQueue(this, flags) | ||
const result = await this.app.assertTime('command '+action.definition.name, 10000, | ||
() => action.runCommand(command, (...args) => emit.emit(...args)), command) | ||
const events = await emit.commit() | ||
if(action.definition.waitForEvents) | ||
await this.app.waitForEvents(reportFinished, events, action.definition.waitForEvents) | ||
return result | ||
}) | ||
}) | ||
) | ||
} | ||
@@ -187,3 +203,3 @@ } | ||
await this.dao.request(['database', 'put'], this.databaseName, 'triggerRoutes', | ||
{ id: triggerName+'=>'+this.name, trigger: triggerName, service: this.name }) | ||
{ id: triggerName + '=>' + this.name, trigger: triggerName, service: this.name }) | ||
if(trigger.definition.queuedBy) { | ||
@@ -195,2 +211,4 @@ const queuedBy = trigger.definition.queuedBy | ||
this.triggerQueue.addCommandHandler(triggerName, async (trig) => { | ||
const profileOp = this.profileLog.begin({ operation: 'queueTrigger', triggerType: triggerName, | ||
triggerId: trig.id, by: trig.by }) | ||
console.log("QUEUED TRIGGER STARTED", trig) | ||
@@ -202,9 +220,42 @@ const reportFinished = trigger.definition.waitForEvents ? 'trigger_'+trig.id : undefined | ||
: new SingleEmitQueue(this, flags) | ||
const routine = async () => { | ||
const routine = this.profileLog.profile({ operation: 'runTrigger', triggerType: triggerName, | ||
commandId: trig.id, by: trig.by }, async () => { | ||
let result | ||
try { | ||
console.log("TRIGGERED!!", trig) | ||
result = await this.app.assertTime('trigger '+trigger.definition.name, 10000, | ||
() => trigger.execute(trig, (...args) => emit.emit(...args)), trig) | ||
console.log("TRIGGER DONE!", trig) | ||
} catch (e) { | ||
console.error(`TRIGGER ${triggerName} ERROR`, e.stack) | ||
throw e | ||
} | ||
const events = await emit.commit() | ||
if(trigger.definition.waitForEvents) | ||
await this.app.waitForEvents(reportFinished, events, trigger.definition.waitForEvents) | ||
return result | ||
}) | ||
try { | ||
routine.key = keyFunction(trig) | ||
} catch(e) { | ||
console.error("QUEUE KEY FUNCTION ERROR", e) | ||
} | ||
console.log("TRIGGER QUEUE KEY", routine.key) | ||
const promise = this.keyBasedTriggerQueues.queue(routine) | ||
await this.profileLog.endPromise(profileOp, promise) | ||
return promise | ||
}) | ||
} else { | ||
this.triggerQueue.addCommandHandler(triggerName, | ||
(trig) => this.profileLog.profile({ operation: 'runTrigger', triggerType: triggerName, | ||
commandId: trig.id, by: trig.by }, async () => { | ||
const reportFinished = trigger.definition.waitForEvents ? 'trigger_'+trig.id : undefined | ||
const flags = { triggerId: trig.id, reportFinished } | ||
const emit = this.app.splitEvents | ||
? new SplitEmitQueue(this, flags) | ||
: new SingleEmitQueue(this, flags) | ||
let result | ||
try { | ||
console.log("TRIGGERED!!", trig) | ||
result = await this.app.assertTime('trigger '+trigger.definition.name, 10000, | ||
() => trigger.execute(trig, (...args) => emit.emit(...args)), trig) | ||
console.log("TRIGGER DONE!", trig) | ||
} catch (e) { | ||
@@ -218,31 +269,4 @@ console.error(`TRIGGER ${triggerName} ERROR`, e.stack) | ||
return result | ||
} | ||
try { | ||
routine.key = keyFunction(trig) | ||
} catch(e) { | ||
console.error("QUEUE KEY FUNCTION ERROR", e) | ||
} | ||
console.log("TRIGGER QUEUE KEY", routine.key) | ||
return this.keyBasedTriggerQueues.queue(routine) | ||
}) | ||
} else { | ||
this.triggerQueue.addCommandHandler(triggerName, async (trig) => { | ||
const reportFinished = trigger.definition.waitForEvents ? 'trigger_'+trig.id : undefined | ||
const flags = { triggerId: trig.id, reportFinished } | ||
const emit = this.app.splitEvents | ||
? new SplitEmitQueue(this, flags) | ||
: new SingleEmitQueue(this, flags) | ||
let result | ||
try { | ||
result = await this.app.assertTime('trigger '+trigger.definition.name, 10000, | ||
() => trigger.execute(trig, (...args) => emit.emit(...args)), trig) | ||
} catch (e) { | ||
console.error(`TRIGGER ${triggerName} ERROR`, e.stack) | ||
throw e | ||
} | ||
const events = await emit.commit() | ||
if(trigger.definition.waitForEvents) | ||
await this.app.waitForEvents(reportFinished, events, trigger.definition.waitForEvents) | ||
return result | ||
}) | ||
}) | ||
) | ||
} | ||
@@ -285,3 +309,5 @@ } | ||
for(const searchIndexer of this.searchIndexers) { | ||
promises.push(searchIndexer.start()) | ||
promises.push(this.profileLog.profile({ | ||
operation: "startIndexer", serviceName: this.name, indexName: searchIndexer.indexName | ||
}, () => searchIndexer.start())) | ||
} | ||
@@ -288,0 +314,0 @@ await Promise.all(promises) |
@@ -22,3 +22,3 @@ const ReactiveDao = require("@live-change/dao") | ||
done = true | ||
reject('timeout') | ||
reject('session observable timeout') | ||
}, timeout) | ||
@@ -25,0 +25,0 @@ observable.observe(observer) |
{ | ||
"name": "@live-change/framework", | ||
"version": "0.4.7", | ||
"version": "0.4.8", | ||
"description": "Live Change Framework - ultimate solution for real time mobile/web apps", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
154745
51
4240
11