Open michaelpb opened 1 year ago
(overlaps with #8 and #3, e.g. finalizing CPart API)
Possibly: Make Modulo.js structure resemble builds more. Build config structure directly (e.g. window.moduloBuild
or window._modulo
) directly, don't use register. Instead when new Modulo
is constructed, the register stuff will be "reapplied" to the config specified (e.g. to get modulo.assets, and modulo.registry.dom, and so forth).
window.modulo.registry.cparts.Component = class Component {
etc, and just very literally / imperatively build up the config structureSo the new top of the file:
if (typeof window === 'undefined' && typeof module !== 'undefined') {
var window = module.exports = {};
}
window._modulo = { // vanilla JS obj with all config
window.moduloCallback
Another thing it would allow is flexible mounting / bootstrapping: Check for window.moduloCallback - if it exists, don't do ANY bootstrapping, instead invoke this function with the vanilla JavaScript objects it just set up. This handles ALL multiple global modulo needs, since you can just write callbacks to do any extra patching needed. It also lets you stop default behavior to do custom loading.
So the new end of the file:
window._modulo = ... // Top of file, just config stuff
window._modulo.registry.utils.
window.moduloCallback = window.moduloCallback || function startModulo (moduloConfig, loader) {
// Do loading / bootstrapping, check for modulo= or mod-cmd= in URL
};
window.moduloCallback(window._modulo, new window.modulo.DOMLoader(window.modulo));
Builds right now are relying on script tags in HTML documents to initialize components. This isn't good. We can then do window.moduloCallback = function () { ... main requires ... }
in the build script to cleanly get the desired behavior.
Modulo injection strategy:
Every registry also creates an "injected" copy that instantiates the thing with a generic / default definition, eg. a way to make a new <Component></Component>
with defaults, but for ANY type of registered thing, including functions and class helpers.
// Injection "hooks":
const Component = modulo.useClass('cparts.Component');
const [ get, set ] = modulo.useFunc('utils.get', 'utils.set');
// Or, more generic, could be done in a way that guesses correct behavior of functions vs classes:
const Component = modulo.use('cparts.Component');
const [ get, set ] = modulo.use([ 'utils.get', 'utils.set' ]);
// An even more generic version could be:
const Component = modulo.use('cparts.Component', { } );
const ShadowComponent = modulo.use('cparts.Component', { mode: "shadow" } );
// Where "{ ... }" gets flattened to the injection dependency object? Or as defaults in the case of a class..?
modulo.utils.getStuff()
gets 'modulo' injected, whilemodulo.registry.utils.getStuff
does not)new EngineName(modulo, conf, def, defConf)
or something, plus a few expected attributes attached afternew
(to avoid inheritence)constructor
would be mostly unused, since the expected properties won't be ready by then. Maybe add a initCallback or something?Engine
Def processor, that creates and sets up attached to cparts (e.g. Modulo gets DOMLoader, Component gets Reconciler, Template gets Templater, and so on), basically an "auto def" of a sub-thingwindow.modulo
as being hard-coded set in JS, but instead only a sideffect of a CPart Modulo Def getting loaded)