refactor: gathering
This commit is contained in:
parent
97536387e6
commit
4d17a99c1b
|
@ -48,7 +48,6 @@ program
|
|||
action,
|
||||
args = [],
|
||||
description,
|
||||
help,
|
||||
name = keys[i],
|
||||
options = [],
|
||||
} = commands[keys[i]];
|
||||
|
|
|
@ -40,9 +40,6 @@ const capitalize = (string) => string.substring(0, 1).toUpperCase() + string.sub
|
|||
*/
|
||||
const camelCase = (string) => string.split(/[_-]/).map(capitalize).join('');
|
||||
|
||||
// Track gathered for HMR.
|
||||
const hotGathered = new Map();
|
||||
|
||||
// Wrap classes to expose their flecks ID and type.
|
||||
const wrapGathered = (Class, id, idProperty, type, typeProperty) => {
|
||||
class Subclass extends Class {
|
||||
|
@ -67,6 +64,8 @@ exports.Flecks = class Flecks {
|
|||
|
||||
flecks = {};
|
||||
|
||||
$$gathered = {};
|
||||
|
||||
hooks = {};
|
||||
|
||||
/**
|
||||
|
@ -184,7 +183,9 @@ exports.Flecks = class Flecks {
|
|||
* Destroy this instance.
|
||||
*/
|
||||
destroy() {
|
||||
this.$$expandedFlecksCache = {};
|
||||
this.config = {};
|
||||
this.$$gathered = {};
|
||||
this.hooks = {};
|
||||
this.flecks = {};
|
||||
}
|
||||
|
@ -366,7 +367,9 @@ exports.Flecks = class Flecks {
|
|||
.map(([path, {mixin}]) => [path, mixin]).filter(([, mixin]) => mixin);
|
||||
debugSilly('mixins: %O', mixinDescription.map(([path]) => path));
|
||||
const Flecks = compose(...mixinDescription.map(([, mixin]) => mixin))(this);
|
||||
return new Flecks(runtime);
|
||||
const instance = new Flecks(runtime);
|
||||
await instance.gatherHooks();
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -414,20 +417,35 @@ exports.Flecks = class Flecks {
|
|||
[exports.ById]: ids,
|
||||
[exports.ByType]: types,
|
||||
};
|
||||
// Register for HMR?
|
||||
hotGathered.set(
|
||||
hook,
|
||||
{
|
||||
check,
|
||||
idProperty,
|
||||
typeProperty,
|
||||
gathered,
|
||||
},
|
||||
);
|
||||
this.$$gathered[hook] = {
|
||||
check,
|
||||
idProperty,
|
||||
typeProperty,
|
||||
gathered,
|
||||
};
|
||||
debug("gathered '%s': %O", hook, Object.keys(gathered[exports.ByType]));
|
||||
return gathered;
|
||||
}
|
||||
|
||||
gathered(type) {
|
||||
return this.$$gathered[type]?.gathered;
|
||||
}
|
||||
|
||||
async gatherHooks() {
|
||||
const gathering = await this.invokeAsync('@flecks/core.gathered');
|
||||
await Promise.all(
|
||||
Object.entries(gathering)
|
||||
.map(([fleck, gathering]) => (
|
||||
Promise.all(
|
||||
Object.entries(gathering)
|
||||
.map(([type, options]) => (
|
||||
this.gather(`${fleck}.${type}`, options)
|
||||
)),
|
||||
)
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a configuration value.
|
||||
*
|
||||
|
@ -814,48 +832,46 @@ exports.Flecks = class Flecks {
|
|||
*
|
||||
* @param {string} fleck
|
||||
*/
|
||||
refreshGathered(fleck) {
|
||||
const it = hotGathered.entries();
|
||||
for (let current = it.next(); current.done !== true; current = it.next()) {
|
||||
const {
|
||||
value: [
|
||||
hook,
|
||||
{
|
||||
check,
|
||||
idProperty,
|
||||
gathered,
|
||||
typeProperty,
|
||||
},
|
||||
],
|
||||
} = current;
|
||||
let raw;
|
||||
// If decorating, gather all again
|
||||
if (this.fleckImplementation(fleck, `${hook}.decorate`)) {
|
||||
raw = this.invokeMerge(hook);
|
||||
debugSilly('%s implements %s.decorate', fleck, hook);
|
||||
}
|
||||
// If only implementing, gather and decorate.
|
||||
else if (this.fleckImplementation(fleck, hook)) {
|
||||
raw = this.invokeFleck(hook, fleck);
|
||||
debugSilly('%s implements %s', fleck, hook);
|
||||
}
|
||||
if (raw) {
|
||||
const decorated = this.checkAndDecorateRawGathered(hook, raw, check);
|
||||
debug('updating gathered %s from %s... %O', hook, fleck, decorated);
|
||||
const entries = Object.entries(decorated);
|
||||
entries.forEach(([type, Class]) => {
|
||||
const {[type]: {[idProperty]: id}} = gathered;
|
||||
const Subclass = wrapGathered(Class, id, idProperty, type, typeProperty);
|
||||
// eslint-disable-next-line no-multi-assign
|
||||
gathered[type] = Subclass;
|
||||
gathered[id] = Subclass;
|
||||
gathered[exports.ById][id] = Subclass;
|
||||
gathered[exports.ByType][type] = Subclass;
|
||||
this.invoke('@flecks/core.hmr.gathered.class', Subclass, hook);
|
||||
});
|
||||
this.invoke('@flecks/core.hmr.gathered', gathered, hook);
|
||||
}
|
||||
}
|
||||
async refreshGathered(fleck) {
|
||||
Object.entries(this.$$gathered)
|
||||
.forEach(([
|
||||
hook,
|
||||
{
|
||||
check,
|
||||
idProperty,
|
||||
gathered,
|
||||
typeProperty,
|
||||
},
|
||||
]) => {
|
||||
let raw;
|
||||
// If decorating, gather all again
|
||||
if (this.fleckImplementation(fleck, `${hook}.decorate`)) {
|
||||
raw = this.invokeMergeAsync(hook);
|
||||
debugSilly('%s implements %s.decorate', fleck, hook);
|
||||
}
|
||||
// If only implementing, gather and decorate.
|
||||
else if (this.fleckImplementation(fleck, hook)) {
|
||||
raw = this.invokeFleck(hook, fleck);
|
||||
debugSilly('%s implements %s', fleck, hook);
|
||||
}
|
||||
if (raw) {
|
||||
const decorated = this.checkAndDecorateRawGathered(hook, raw, check);
|
||||
debug('updating gathered %s from %s...', hook, fleck);
|
||||
debugSilly('%O', decorated);
|
||||
const entries = Object.entries(decorated);
|
||||
entries.forEach(([type, Class]) => {
|
||||
const {[type]: {[idProperty]: id}} = gathered;
|
||||
const Subclass = wrapGathered(Class, id, idProperty, type, typeProperty);
|
||||
// eslint-disable-next-line no-multi-assign
|
||||
gathered[type] = Subclass;
|
||||
gathered[id] = Subclass;
|
||||
gathered[exports.ById][id] = Subclass;
|
||||
gathered[exports.ByType][type] = Subclass;
|
||||
this.invoke('@flecks/core.hmr.gathered.class', Subclass, hook);
|
||||
});
|
||||
this.invoke('@flecks/core.hmr.gathered', gathered, hook);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -44,14 +44,14 @@ export const hooks = {
|
|||
*/
|
||||
username: undefined,
|
||||
}),
|
||||
'@flecks/core.gathered': () => ({
|
||||
models: {typeProperty: 'name'},
|
||||
}),
|
||||
'@flecks/core.hmr.gathered': (gathered, hook, flecks) => {
|
||||
if ('@flecks/db/server.models' === hook) {
|
||||
register(gathered, flecks.db.sequelize);
|
||||
}
|
||||
},
|
||||
'@flecks/core.starting': (flecks) => {
|
||||
flecks.db.Models = flecks.gather('@flecks/db/server.models', {typeProperty: 'name'});
|
||||
},
|
||||
'@flecks/docker.containers': containers,
|
||||
'@flecks/server.up': Flecks.priority(
|
||||
async (flecks) => {
|
||||
|
@ -63,17 +63,26 @@ export const hooks = {
|
|||
|
||||
export const mixin = (Flecks) => class FlecksWithDb extends Flecks {
|
||||
|
||||
db = {
|
||||
Models: {},
|
||||
$$sequelize: undefined,
|
||||
get sequelize() {
|
||||
return this.$$sequelize;
|
||||
},
|
||||
set sequelize(sequelize) {
|
||||
this.$$sequelize = sequelize;
|
||||
this.transaction = sequelize.transaction.bind(sequelize);
|
||||
},
|
||||
transaction: () => {},
|
||||
};
|
||||
constructor(runtime) {
|
||||
super(runtime);
|
||||
if (!this.db) {
|
||||
this.db = {};
|
||||
}
|
||||
Object.defineProperty(this.db, 'Models', {get: () => this.gathered('@flecks/db/server.models')});
|
||||
let $$sequelize;
|
||||
let $$transaction = (fn) => fn();
|
||||
Object.defineProperty(
|
||||
this.db,
|
||||
'sequelize',
|
||||
{
|
||||
get: () => $$sequelize,
|
||||
set: (sequelize) => {
|
||||
$$sequelize = sequelize;
|
||||
$$transaction = sequelize.transaction.bind(sequelize);
|
||||
},
|
||||
},
|
||||
);
|
||||
Object.defineProperty(this.db, 'transaction', {get: () => $$transaction});
|
||||
}
|
||||
|
||||
};
|
||||
|
|
14
packages/db/test/server/models.js
Normal file
14
packages/db/test/server/models.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
import {Flecks} from '@flecks/core';
|
||||
import {expect} from 'chai';
|
||||
|
||||
it('automatically gathers models', async () => {
|
||||
const flecks = await Flecks.from({
|
||||
flecks: {
|
||||
'@flecks/core': await import('@flecks/core'),
|
||||
'@flecks/db/server': await import('../../src/server'),
|
||||
'@test/thing': await import('./thing'),
|
||||
},
|
||||
});
|
||||
expect(flecks.db.Models.Foo)
|
||||
.to.not.be.undefined;
|
||||
});
|
7
packages/db/test/server/thing/index.js
Normal file
7
packages/db/test/server/thing/index.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
import Model from '../../../src/model';
|
||||
|
||||
export const hooks = {
|
||||
'@flecks/db/server.models': () => ({
|
||||
Foo: class extends Model {},
|
||||
}),
|
||||
};
|
|
@ -8,9 +8,11 @@ export * from './hooks';
|
|||
export {Packet, Packer, ValidationError} from './packet';
|
||||
|
||||
export const hooks = {
|
||||
'@flecks/core.starting': (flecks) => {
|
||||
flecks.socket.Packets = flecks.gather('@flecks/socket.packets', {check: badPacketsCheck});
|
||||
},
|
||||
'@flecks/core.gathered': () => ({
|
||||
packets: {
|
||||
check: badPacketsCheck,
|
||||
},
|
||||
}),
|
||||
'@flecks/socket.packets': (flecks) => ({
|
||||
Bundle: Bundle(flecks),
|
||||
Redirect,
|
||||
|
@ -26,12 +28,16 @@ export const hooks = {
|
|||
|
||||
export const mixin = (Flecks) => class FlecksWithSocket extends Flecks {
|
||||
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
constructor(runtime) {
|
||||
super(runtime);
|
||||
if (!this.socket) {
|
||||
this.socket = {};
|
||||
}
|
||||
this.socket.Packets = {};
|
||||
Object.defineProperty(
|
||||
this.socket,
|
||||
'Packets',
|
||||
{get: () => this.gathered('@flecks/socket.packets')},
|
||||
);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
14
packages/socket/test/server/packets.js
Normal file
14
packages/socket/test/server/packets.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
import {Flecks} from '@flecks/core';
|
||||
import {expect} from 'chai';
|
||||
|
||||
it('automatically gathers packets', async () => {
|
||||
const flecks = await Flecks.from({
|
||||
flecks: {
|
||||
'@flecks/core': await import('@flecks/core'),
|
||||
'@flecks/socket': await import('../../src'),
|
||||
'@test/thing': await import('./thing'),
|
||||
},
|
||||
});
|
||||
expect(flecks.socket.Packets.Foo)
|
||||
.to.not.be.undefined;
|
||||
});
|
7
packages/socket/test/server/thing/index.js
Normal file
7
packages/socket/test/server/thing/index.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
import Packet from '../../../src/packet/packet';
|
||||
|
||||
export const hooks = {
|
||||
'@flecks/socket.packets': () => ({
|
||||
Foo: class extends Packet {},
|
||||
}),
|
||||
};
|
Loading…
Reference in New Issue
Block a user