-
Notifications
You must be signed in to change notification settings - Fork 668
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Plugins API and documentation. #444
Conversation
Just to stick my oar in.. I've 3 modules/plugins I'd like to write for the current state of thelounge as my motivations are to have a more Slack like IRC experience:
my gut feeling is that 1 and 2 are probably extensions of the front end client as they effect presentation but 3 is probably an extension for the backend as it is similar to an additional command these might be good example ideas instead of a hello world/dolly and i'm happy to dive in and work on them if someone gives me some pointers |
@ruspow: it's not quite ready yet, it's more like a draft than anything else. But you can look at the eval plugin there: https://github.com/thelounge/lounge/blob/e15af1f7e1ff5217d815dbf9f934506c3126b483/packages/eval/index.js It does not use the suggested API however, so it's still fairly limited and weird to work with. |
Unsure if worth mentioning, but the way https://github.com/zeit/hyperterm has developed support for plugins is interesting and quite powerful (using redux). |
I haven't looked at their plugin API, but I noticed that they had more than 150 plugins a month after the project was created, so it seems indeed that they made it easy and powerful to write plugins! |
Implements `/eval client <code>` to execute code on the client, and `/eval server <code>` to execute code on the server.
This is my current WIP API. I'm opening this PR to keep track of discussions and allow people to give their feedback on it. Maintainers with commit access feel free to push to this branch directly. Other people: feel free to create pull requests against the
packages
branch.For now I only have created stubs for the basics, to show the general ideal. I will refine, move things around and make sure to order everything in a way that makes sense incrementally. This will likely require rewriting quite a few things for it to work, but it should be doable with a lot of copy-pasting action.
It might look a bit weird for now, but do keep in mind I have some kind of fancy RPC/data sharing between the client and the server planned, kind of like #275. I still haven't worked out the details of it. I am not planning on using EventEmitters at the moment (I will provide
onXXX
functions and methods to append/prepend to the function stack instead). I don't know how viable this is, but I love engineering new ways.Design principle
My idea of a nice and powerful plugins API is to not restrict plugins at all. In order to provide plugins this, I suggest The Lounge and plugins share and run on top of the same core. Everything exposed by the core and plugins can be changed by other plugins through a practice known as monkey-patching. The idea behind this is very simple: assuming the core is sufficiently modular, most tasks that a plugin would want to achieve could be achieved by replacing or altering code in the core. Most of the currently most requested features would become relatively easy to implement in such an environment: for example, logging scrollback to a database could be accomplished by hooking the messages array and dynamically store and fetch back messages from the database backend. Another example: custom authentication and account provisionning would be achievable by replacing the current user loading function to fetch from however the backend works.
Additionally, specialized plugins will be able to provider higher level APIs which other plugins will be able to take advantage of. For example, custom command handlers could be handled by a command manager plugin that makes it easy to test/debug and change commands on a per-server/user/client basis.
Server-side and client-side plugins will run independantly, allowing users to install their own plugins without introducing a security risk on the server side. With the above point in mind, an abstraction layer could easily be made to allow running the same code on both the client and the server, dynamically using the best approach when available.
Data protection is handled by plugins by simply making variables and functions inaccessible outside of them by either not adding them to
module.exports
, or on the client-side by using closures.Module installation and loading
The current plan is to load every modules on the server start, and to load every client-side modules when the page is loaded. Utility functions to support dynamic unloading of modules (by wrapping function replacements and hooking operations in a logged manner that allows restoring the original functions on unload). Unloading isn't an issue on the client (where dynamic unloading will be the most used) as the user can just reload the page.
Modules are responsible of turning themselves on and off in order to reduce the complexity of the plugins engine. If a user wishes to not use a module, said module should not be installed. The only exception to this rule will be a plugins blacklist configuration option that will allow to prevent a module from being loaded at all.
Client-side only modules, which will be installable by users, will be required to come in an archive format with all of its dependencies included as the server won't run npm or any other kind of package manager for security reasons. Server-side modules will have absolute freedom in the way they are distributed (git, npm, svn, zip archives). Their only requirement will be their availability in a specifically designated folder (either directly or through a symlink).
Client-side resources will automatically be mounted at
/packages/$name/
and will point to a packagesclient/
directory. This is how plugins are expected to serve their client-side content.Considerations and drawbacks
The monkey-patching method have obvious drawbacks:
_
in the code), then code will break.