Compare commits

...

1 Commits

Author SHA1 Message Date
Julien Fontanet
d32c5b31e7 WiP: feat(mixin): support for lazy mixins 2022-06-23 16:38:13 +02:00
2 changed files with 44 additions and 13 deletions

View File

@@ -2,7 +2,12 @@
const camelCase = require('lodash/camelCase')
const { defineProperties, defineProperty, keys } = Object
const {
defineProperties,
defineProperty,
hasOwn = Function.prototype.call.bind(Object.prototype.hasOwnProperty),
keys,
} = Object
const noop = Function.prototype
const MIXIN_CYCLIC_DESCRIPTOR = {
@@ -13,23 +18,49 @@ const MIXIN_CYCLIC_DESCRIPTOR = {
}
module.exports = function mixin(object, mixins, args) {
const importing = { __proto__: null }
const importers = { __proto__: null }
function instantiateMixin(name, Mixin) {
defineProperty(object, name, MIXIN_CYCLIC_DESCRIPTOR)
const instance = new Mixin(object, ...args)
defineProperty(object, name, {
value: instance,
})
return instance
}
// add lazy property for each of the mixin, this allows mixins to depend on
// one another without any special ordering
const descriptors = {}
const descriptors = {
loadMixin(name) {
if (hasOwn(this, name)) {
return Promise.resolve(this[name])
}
let promise = importing[name]
if (promise === undefined) {
const clean = () => {
delete importing[name]
}
promise = importers[name]().then(Mixin => instantiateMixin(name, Mixin))
promise.then(clean, clean)
importing[name] = promise
}
return promise
},
}
keys(mixins).forEach(name => {
const Mixin = mixins[name]
name = camelCase(name)
descriptors[name] = {
configurable: true,
get: () => {
defineProperty(object, name, MIXIN_CYCLIC_DESCRIPTOR)
const instance = new Mixin(object, ...args)
defineProperty(object, name, {
value: instance,
})
return instance
},
if (Mixin.prototype === undefined) {
importers[name] = Mixin(name)
} else {
descriptors[name] = {
configurable: true,
get: () => instantiateMixin(name, Mixin),
}
}
})
defineProperties(object, descriptors)

View File

@@ -16,7 +16,7 @@
},
"preferGlobal": false,
"engines": {
"node": ">=6"
"node": ">=7.6"
},
"dependencies": {
"bind-property-descriptor": "^2.0.0",