html icon indicating copy to clipboard operation
html copied to clipboard

Composable lifecycle hooks

Open LeaVerou opened this issue 9 months ago • 4 comments

Background

Currently web component lifecycle hooks exist as instance functions with special names like connectedCallback(), attributeChangedCallback(), disconnectedCallback() and so on.

This means that composing multiple listeners from different sources has a very poor DX. You basically have to wrap the existing connectedCallback() with a new one that calls it. Remember how event handling was before addEventListener() / attachEvent()? Yes, that. And good luck undoing this operation.

Why would you need to do that?

  • Having mixins and utility methods for common custom element behaviors, e.g. defining reflected props
  • If any of the custom attributes proposals gets adopted, this will become even more important since each attribute will need its own lifecycle hooks.

Proposed solution

You basically need a lightweight pub/sub mechanism that doesn't carry the baggage of events, but allows independently adding and removing callbacks and passing arguments to them (for attributeChangedCallback()).

As a strawman just to start the conversation, it could look similar to addEventListener() (addLifecycleListener?) with type being connected, disconnected, adopted, attribute.

This can co-exist with the current lifecycle hooks, as long as the order of execution is well defined (presumably the current lifecycle hooks would be executed first).

LeaVerou avatar Apr 27 '24 02:04 LeaVerou

Sorry thought I could record the problem here is the test scene (using Core tokens and traits only) and a before and after screen sho.t

fvtt-Scene-test-IBXVXLgkLSjQk20g.json image image

StevenEvans1966 avatar May 03 '24 20:05 StevenEvans1966

Also found that moving the Big Daemonette of Slaanesh up results in the following errors

Foundry VTT | Deleted ActiveEffect with id [HbqMfCGjqs2VlQQR] in parent ActorDelta [ywx5YROrcPUyF65k] foundry.js:68326 undefined id [HbqMfCGjqs2VlQQR] does not exist in the EmbeddedCollectionDelta collection. fetch @ foundry.js:68326 notify @ foundry.js:68223 error @ foundry.js:68260 _handleError @ foundry.js:3468 (anonymous) @ foundry.js:3450 value @ socket.js:532 value @ socket.js:459 L.emit @ index.mjs:136 (anonymous) @ manager.js:207 Promise.then (async) it @ websocket-constructor.browser.js:5 value @ manager.js:206 L.emit @ index.mjs:136 value @ index.js:131 value @ manager.js:193 L.emit @ index.mjs:136 value @ socket.js:324 L.emit @ index.mjs:136 value @ transport.js:97 value @ transport.js:89 ws.onmessage @ websocket.js:69 commons.js:8114 Uncaught (in promise) Error: undefined. undefined id [HbqMfCGjqs2VlQQR] does not exist in the EmbeddedCollectionDelta collection. [No packages detected] at EmbeddedCollectionDelta.get (file:///D:/Program%20Files/Foundry%20Virtual%20Tabletop%20v11/resources/app/common/abstract/embedded-collection.mjs:164:36) at file:///D:/Program%20Files/Foundry%20Virtual%20Tabletop%20v11/resources/app/dist/database/backend/server-backend.mjs:1:5212 at Array.map () at ServerDatabaseBackend._deleteDocuments (file:///D:/Program%20Files/Foundry%20Virtual%20Tabletop%20v11/resources/app/dist/database/backend/server-backend.mjs:1:5202) at ServerDatabaseBackend.delete (file:///D:/Program%20Files/Foundry%20Virtual%20Tabletop%20v11/resources/app/common/abstract/backend.mjs:182:17) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Semaphore._try (file:///D:/Program%20Files/Foundry%20Virtual%20Tabletop%20v11/resources/app/common/utils/semaphore.mjs:101:17) _handleError @ foundry.js:3466 (anonymous) @ foundry.js:3450 value @ socket.js:532 value @ socket.js:459 L.emit @ index.mjs:136 (anonymous) @ manager.js:207 await in (anonymous) (async) checkAreas @ wfrp4e.js:12376 await in checkAreas (async) (anonymous) @ wfrp4e.js:23639 #call @ foundry.js:730 callAll @ foundry.js:687 callback @ foundry.js:13738 (anonymous) @ foundry.js:13711 #handleUpdateDocuments @ foundry.js:13711 await in #handleUpdateDocuments (async) _updateDocuments @ foundry.js:13458 await in _updateDocuments (async) update @ commons.js:8677 await in update (async) updateDocuments @ commons.js:8001 updateEmbeddedDocuments @ commons.js:8233 moveMany @ foundry.js:35648 _handleMovement @ foundry.js:1963 (anonymous) @ foundry.js:2082 setTimeout (async) _onPan @ foundry.js:2082 onDown @ foundry.js:1660 _executeKeybind @ foundry.js:2502 _processKeyboardContext @ foundry.js:2543 _handleKeyboardEvent @ foundry.js:2601 (anonymous) @ foundry.js:2227 commons.js:8807 Foundry VTT | Deleted ActiveEffect with id [7h3dIAL0WNDq1Iju] in parent ActorDelta [uzxKkO6GrLgBIEeO]

StevenEvans1966 avatar May 08 '24 17:05 StevenEvans1966

Just tested with 7.2 this issue has not been fixed. I assume it has been rolled into another task

StevenEvans1966 avatar Jun 07 '24 09:06 StevenEvans1966

Yes this wasn't intended to be closed

moo-man avatar Jun 07 '24 18:06 moo-man