You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/PLAN.md
+61-4Lines changed: 61 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,10 +18,12 @@ Make a page that fetches extensions from some remote repository
18
18
19
19
That repository must include only moderated extensions. Moderation process should require extension's source code and, if differs from usual, a build manual. Every extension update must go through the moderation process. This is the only way to make custom extensions secure, I guess
20
20
21
-
Those extensions should be loaded once at application launch. Programming language must be a JavaScript. Any framework is ok, as long as it is capable running in a browser. Extensions need to be able to communicate with launcher
21
+
Those extensions should be loaded once at application launch. Programming language must be a JavaScript. Any framework is ok, as long as it is capable running in a browser. Extensions will be able to communicate with the launcher
22
22
23
23
### More
24
24
25
+
**Previous implementation details**
26
+
25
27
Any JS code can be dynamically fetched in runtime from somewhere and executed with the `new Function` constructor. Example (I implemented it in [one of my projects](https://github.com/notwindstone/tsuki)):
26
28
27
29
```ts
@@ -44,11 +46,66 @@ Unfortunately, if VSCode, Obsidian, Vencord and other apps can't implement a sec
44
46
45
47
Btw, Figma chose security over functionality with their `iframe` approach
46
48
47
-
// 19.09.2025 update
49
+
**Latest implementation details (19.09.2025)**
50
+
51
+
Microfrontends supremacy >.<
52
+
53
+
Using a Module Federation Runtime we can load any Vue component just like an ordinary component in the node tree. To make it possible for plugins to render components anywhere, a `<Teleport />` could be used. Module Federation Runtime also allows us to share dependencies, so the final extension budle size should be low.
54
+
55
+
For other JS frameworks, we can run them using the previous implementation: `new Function`.
48
56
49
-
consider using runtime microfrontends. mounting components can be achieved using portals (react)/teleports (vue)
57
+
Launcher should expose everything that it can through the `window.__KAEDE__`. Previously, communication was done using the `window.postMessage` function, but now I came up with the idea of exposing an array of functions for almost every action in app. That array can be changed by extensions, and then the launcher will execute every function listed in that array.
58
+
59
+
For example, see the next code:
60
+
61
+
```ts
62
+
/** Launcher */
63
+
window.postMessage("kaede-route-changed", /* some data */)
While it works, it doesn't look good to me. Adding a lot of window listeners can affect a launcher performance. If user has 20 extensions, that `handleKaedeMessages` function will fire on every new event in every extension, even if the event wasn't needed.
for (consthookof window.__KAEDE__.hooks.onRouteChange.before) {
103
+
hook({ pathname });
104
+
}
105
+
});
106
+
```
50
107
51
-
plugin manifest should also contain a `customLoader: string | undefined` field
108
+
Extensions are not needed to listen for window events anymore. Only specified actions will be triggered. Must be a perfect solution? Maybe. I'm not sure that this will work, because, well, launcher doesn't have the same scope as that extension code block where `window.__KAEDE__` was reassigned (?)
0 commit comments