Skip to content

Commit

Permalink
Unlock controller loading & logDebugActivity
Browse files Browse the repository at this point in the history
log `controller#lazy:loading` & `controller#lazy:loaded`
  • Loading branch information
smnandre committed Dec 22, 2024
1 parent f681ec8 commit 0e5abca
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 38 deletions.
55 changes: 36 additions & 19 deletions src/StimulusBundle/assets/dist/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,50 @@ class StimulusLazyControllerHandler {
this.lazyLoadNewControllers(document.documentElement);
}
lazyLoadExistingControllers(element) {
this.queryControllerNamesWithin(element).forEach((controllerName) => this.loadLazyController(controllerName));
Array.from(element.querySelectorAll(`[${controllerAttribute}]`))
.flatMap(extractControllerNamesFrom)
.forEach((controllerName) => this.loadLazyController(controllerName));
}
async loadLazyController(name) {
if (canRegisterController(name, this.application)) {
if (this.lazyControllers[name] === undefined) {
return;
}
const controllerModule = await this.lazyControllers[name]();
registerController(name, controllerModule.default, this.application);
loadLazyController(name) {
if (!this.lazyControllers[name]) {
return;
}
const controllerLoader = this.lazyControllers[name];
delete this.lazyControllers[name];
if (!canRegisterController(name, this.application)) {
return;
}
this.application.logDebugActivity(name, 'lazy:loading');
controllerLoader()
.then((controllerModule) => {
this.application.logDebugActivity(name, 'lazy:loaded');
registerController(name, controllerModule.default, this.application);
})
.catch((error) => {
console.error(`Error loading controller "${name}":`, error);
});
}
lazyLoadNewControllers(element) {
if (Object.keys(this.lazyControllers).length === 0) {
return;
}
new MutationObserver((mutationsList) => {
for (const { attributeName, target, type } of mutationsList) {
switch (type) {
case 'attributes': {
if (attributeName === controllerAttribute &&
target.getAttribute(controllerAttribute)) {
extractControllerNamesFrom(target).forEach((controllerName) => this.loadLazyController(controllerName));
for (const mutation of mutationsList) {
switch (mutation.type) {
case 'childList': {
for (const node of mutation.addedNodes) {
if (node instanceof Element) {
extractControllerNamesFrom(node).forEach((controllerName) => {
this.loadLazyController(controllerName);
});
}
}
break;
}
case 'childList': {
this.lazyLoadExistingControllers(target);
case 'attributes': {
if (mutation.attributeName === controllerAttribute) {
extractControllerNamesFrom(mutation.target).forEach((controllerName) => this.loadLazyController(controllerName));
}
}
}
}
Expand All @@ -58,9 +78,6 @@ class StimulusLazyControllerHandler {
childList: true,
});
}
queryControllerNamesWithin(element) {
return Array.from(element.querySelectorAll(`[${controllerAttribute}]`)).flatMap(extractControllerNamesFrom);
}
}
function registerController(name, controller, application) {
if (canRegisterController(name, application)) {
Expand Down
58 changes: 39 additions & 19 deletions src/StimulusBundle/assets/src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,38 +64,58 @@ class StimulusLazyControllerHandler {
}

private lazyLoadExistingControllers(element: Element) {
Array.from(element.querySelectorAll(`[${controllerAttribute}]`)).flatMap(extractControllerNamesFrom).forEach(
(controllerName) => this.loadLazyController(controllerName)
);
Array.from(element.querySelectorAll(`[${controllerAttribute}]`))
.flatMap(extractControllerNamesFrom)
.forEach((controllerName) => this.loadLazyController(controllerName));
}

private async loadLazyController(name: string) {
if (canRegisterController(name, this.application)) {
if (this.lazyControllers[name] === undefined) {
return;
}
private loadLazyController(name: string) {
if (!this.lazyControllers[name]) {
return;
}

const controllerModule = await this.lazyControllers[name]();
// Delete the loader to avoid loading it twice
const controllerLoader = this.lazyControllers[name];
delete this.lazyControllers[name];

registerController(name, controllerModule.default, this.application);
if (!canRegisterController(name, this.application)) {
return;
}

this.application.logDebugActivity(name, 'lazy:loading');

controllerLoader()
.then((controllerModule) => {
this.application.logDebugActivity(name, 'lazy:loaded');
registerController(name, controllerModule.default, this.application);
})
.catch((error) => {
console.error(`Error loading controller "${name}":`, error);
});
}

private lazyLoadNewControllers(element: Element) {
if (Object.keys(this.lazyControllers).length === 0) {
return;
}
new MutationObserver((mutationsList) => {
for (const { attributeName, target, type } of mutationsList) {
switch (type) {
for (const mutation of mutationsList) {
switch (mutation.type) {
case 'childList': {
this.lazyLoadExistingControllers(target as Element);
// @ts-ignore
for (const node of mutation.addedNodes) {
if (node instanceof Element) {
extractControllerNamesFrom(node).forEach((controllerName) => {
this.loadLazyController(controllerName);
});
}
}
break;
}

case 'attributes': {
if (
attributeName === controllerAttribute &&
(target as Element).getAttribute(controllerAttribute)
) {
extractControllerNamesFrom(target as Element).forEach((controllerName) =>
if (mutation.attributeName === controllerAttribute) {
extractControllerNamesFrom(mutation.target as Element).forEach((controllerName) =>
this.loadLazyController(controllerName)
);
}
Expand Down

0 comments on commit 0e5abca

Please sign in to comment.