-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #17 from baethon/events
Events
- Loading branch information
Showing
23 changed files
with
1,126 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
const Event = require('./event') | ||
|
||
class Deleted extends Event { | ||
static get eventName () { | ||
return 'deleted' | ||
} | ||
|
||
/** | ||
* @param {*} results | ||
*/ | ||
constructor (results) { | ||
super() | ||
|
||
this.result = results | ||
} | ||
} | ||
|
||
module.exports = Deleted |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
const Event = require('./event') | ||
const Deleted = require('./deleted') | ||
|
||
class Deleting extends Event { | ||
static get eventName () { | ||
return 'deleting' | ||
} | ||
|
||
/** | ||
* @param {String|String[]} returning | ||
*/ | ||
constructor (returning) { | ||
super() | ||
this.returning = returning | ||
} | ||
|
||
mutateQueryBuilder (qb) { | ||
qb._single.returning = this.returning | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
toAfterEvent (results) { | ||
return new Deleted(results) | ||
} | ||
} | ||
|
||
module.exports = Deleting |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
const { KexError } = require('../errors') | ||
|
||
class Event { | ||
static get eventName () { | ||
throw new KexError('Event name should be set in child class') | ||
} | ||
|
||
constructor () { | ||
this.cancelled = false | ||
this.emitted = false | ||
} | ||
|
||
cancel () { | ||
this.cancelled = true | ||
} | ||
|
||
markEmitted () { | ||
this.emitted = true | ||
} | ||
|
||
mutateQueryBuilder (qb) { | ||
// extend on when required | ||
} | ||
|
||
/** | ||
* @param {*} results | ||
* @return {Event} | ||
*/ | ||
toAfterEvent (results) { | ||
throw new KexError('toAfterEvent() should be implemented in the child class') | ||
} | ||
} | ||
|
||
module.exports = Event |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
const Event = require('./event') | ||
|
||
class Fetched extends Event { | ||
static get eventName () { | ||
return 'fetched' | ||
} | ||
|
||
/** | ||
* @param {Object|Object[]} results | ||
*/ | ||
constructor (results) { | ||
super() | ||
|
||
this.results = results | ||
} | ||
} | ||
|
||
module.exports = Fetched |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
const Event = require('./event') | ||
const Fetched = require('./fetched') | ||
|
||
class Fetching extends Event { | ||
static get eventName () { | ||
return 'fetching' | ||
} | ||
|
||
/** | ||
* @param {*} results | ||
* @return {import('./fetched')} | ||
*/ | ||
toAfterEvent (results) { | ||
return new Fetched(results) | ||
} | ||
} | ||
|
||
module.exports = Fetching |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
module.exports = { | ||
EventsPipeline: require('./pipeline'), | ||
DeletingEvent: require('./deleting'), | ||
DeletedEvent: require('./deleted'), | ||
FetchingEvent: require('./fetching'), | ||
FetchedEvent: require('./fetched'), | ||
UpdatingEvent: require('./updating'), | ||
UpdatedEvent: require('./updated'), | ||
InsertingEvent: require('./inserting'), | ||
InsertedEvent: require('./inserted') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
const Event = require('./event') | ||
|
||
class Inserted extends Event { | ||
static get eventName () { | ||
return 'inserted' | ||
} | ||
|
||
/** | ||
* @param {*} results | ||
* @param {Object|Object[]} values | ||
*/ | ||
constructor (results, values) { | ||
super() | ||
this.results = results | ||
this.values = values | ||
} | ||
} | ||
|
||
module.exports = Inserted |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
const Event = require('./event') | ||
const Inserted = require('./inserted') | ||
|
||
class Inserting extends Event { | ||
static get eventName () { | ||
return 'inserting' | ||
} | ||
|
||
/** | ||
* @param {Object|Object[]} values | ||
* @param {String|String[]} returning | ||
*/ | ||
constructor (values, returning) { | ||
super() | ||
|
||
this.values = values | ||
this.returning = returning | ||
} | ||
|
||
mutateQueryBuilder (qb) { | ||
qb._single.insert = this.values | ||
qb._single.returning = this.returning | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
toAfterEvent (results) { | ||
return new Inserted(results, this.values) | ||
} | ||
} | ||
|
||
module.exports = Inserting |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/** @typedef { import('./event') } Event */ | ||
|
||
/** | ||
* @callback EventListener | ||
* @param {Event} event | ||
*/ | ||
|
||
/** @typedef {Map<String, EventListener[]>} Listeners */ | ||
|
||
class EventsPipeline { | ||
/** | ||
* @param {Array} listeners entries for listeners mapTo | ||
*/ | ||
constructor (listeners = []) { | ||
/** @type {Listeners} */ | ||
this.listeners = new Map(listeners) | ||
} | ||
|
||
/** | ||
* @param {String} eventName | ||
* @param {EventListener} listener | ||
* @return {Function} a callback which removes the listener | ||
*/ | ||
on (eventName, listener) { | ||
const list = this.listeners.get(eventName) || [] | ||
this.listeners.set(eventName, list.concat(listener)) | ||
|
||
return () => { | ||
const list = this.listeners.get(eventName) | ||
const index = list.indexOf(listener) | ||
|
||
if (index >= 0) { | ||
list.splice(index, 1) | ||
this.listeners.set(eventName, list) | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Execute all listeners of given event. | ||
* | ||
* The listeners are called serially. | ||
* Event instance can be emitted only once. To repeat it emission, create new event. | ||
* | ||
* @param {Event} event | ||
* @param {*} [bind] value to bind with the listener | ||
* @return {Promise<Boolean>} the result of calling the listener; | ||
* FALSE indicates that event was cancelled | ||
*/ | ||
async emit (event, bind = null) { | ||
if (event.emitted) { | ||
return false | ||
} | ||
|
||
const { eventName } = event.constructor | ||
const list = this.listeners.get(eventName) || [] | ||
|
||
event.markEmitted() | ||
|
||
for (let i = 0; i < list.length; i++) { | ||
const fn = list[i] | ||
|
||
await fn.call(bind, event) | ||
|
||
if (event.cancelled) { | ||
return false | ||
} | ||
} | ||
|
||
return true | ||
} | ||
|
||
/** | ||
* Create copy of current instance. | ||
* | ||
* This method makes sure that all lists are dereferenced. | ||
* | ||
* @return {EventsPipeline} | ||
*/ | ||
clone () { | ||
const entries = Array.from(this.listeners.entries()) | ||
|
||
return new this.constructor(entries.map(([name, listeners]) => ([ | ||
name, | ||
[...listeners] | ||
]))) | ||
} | ||
} | ||
|
||
module.exports = EventsPipeline |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
const Event = require('./event') | ||
|
||
class Updated extends Event { | ||
static get eventName () { | ||
return 'updated' | ||
} | ||
|
||
/** | ||
* @param {*} results | ||
* @param {Object|Object[]} values | ||
*/ | ||
constructor (results, values) { | ||
super() | ||
|
||
this.results = results | ||
this.values = values | ||
} | ||
} | ||
|
||
module.exports = Updated |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
const Event = require('./event') | ||
const Updated = require('./updated') | ||
|
||
class Updating extends Event { | ||
static get eventName () { | ||
return 'updating' | ||
} | ||
|
||
/** | ||
* @param {Object|Object[]} values | ||
* @param {String|String[]} returning | ||
*/ | ||
constructor (values, returning) { | ||
super() | ||
|
||
this.values = values | ||
this.returning = returning | ||
} | ||
|
||
mutateQueryBuilder (qb) { | ||
qb._single.update = this.values | ||
qb._single.returning = this.returning | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
toAfterEvent (results) { | ||
return new Updated(results, this.values) | ||
} | ||
} | ||
|
||
module.exports = Updating |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.