modulojs / modulo

A drop-in JavaScript framework for modular web components, kept to about 2000 lines
https://modulojs.org/
GNU Lesser General Public License v2.1
14 stars 1 forks source link

Complete Engine & Util interface #32

Open michaelpb opened 1 year ago

michaelpb commented 1 year ago

michaelpb commented 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).

So 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

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.

michaelpb commented 1 year ago

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..?