Skip to content

corpusculejs/corpuscule

Repository files navigation

🛠 Status: In Development

Corpuscule is currently under heavy development. Feedback is always welcome, but be careful with using it in production. API is not ready yet and can receive large changes.

Corpuscule

CI Status GitHub license Coverage Bugs Vulnerabilities

Corpuscule is a set of libraries built on top of Web Components standard. It provides all necessary tools to built whole application from scratch including redux connector, router and form utils.

Principles

Be universal

You can use almost all Corpuscule tools with any Web Component based system, like Polymer, LitElement or SkateJS. They are not bound to @corpuscule/element and implemented with only web components lifecycle hooks. Also, @corpuscule/element can use any renderer you want: lit-html, hyperHTML, preact or even React.

Be small yet powerful

Bundle size matters. It becomes critical for people with a slow internet connection. Corpuscule already uses Web Components standard that takes care of the component system, so everything it needs is to have as many useful features as possible in smallest size as possible.

Be at the bleeding edge of JavaScript

Features adding to the JavaScript language simplify developer's life, give new opportunities and solve problems like security holes. That's why Corpuscule is trying to be on the bleeding edge of language development and use the latest features.

Separate semantics from logic

Semantics is a keystone of the web for a long time now. We used to make our markup as meaningful as possible. We use <article> instead of <div> to wrap our articles because <article> makes way more sense than a simple <div>. We have <header>, <section> and <footer> tags to split our layout to parts properly.

However, with the React popularity growing we have got not only great solutions but also a handful of doubtful patterns. One of them is an approach to put logic into the markup. This approach brings such components as <Provider>, <Suspense>, <Connect(MyComponent)> etc. that can have no own markup at all!

So while it is acceptable for React components since they exist only on the JS level, it could be wrong for web components which have their representation in the DOM. The existence of only logic components in DOM breaks the idea of semantics.

That's why Corpuscule suggests a slightly different approach. Since it is just logic, we can apply it to semantic web components using decorators and class properties. It means that single web component could be a component connected to Redux, custom context provider and router outlet at the same time.

Technologies

Some technological solutions of Corpuscule could be surprising and confusing. This section provides explanation of why this or that solution has been chosen.

Decorators (stage 2)

The new decorators specification could become a game-changer in the JavaScript world (along with private class fields/methods ). Decorators add a powerful system of metaprogramming to the JS language allowing to step into all stages of the class lifecycle, to manipulate class fields in the very declarative yet incredibly flexible way. You still could achieve some similar results using class mixins and static methods with property definition, but it is way less descriptive and has its drawbacks.

Unfortunately, the initial proposal Corpuscule was built on is deprecated due to serious performance issues. There is a new static decorator proposal, but it does not have Babel implementation yet, and it is not defined when it will.

That is the reason Corpuscule moves to an emulation of static decorator proposal. What does emulation mean? Well, it is not a specification-correct implementation, but it implements basic ideas of the proposal. Emulation uses the legacy decorator proposal (stage 1) that is well-supported by Babel and Typescript supplemented with a custom solution: a Babel plugin that adds missing parts to the code generated by the legacy plugin.

Symbols

This solution of Corpuscule may confuse you. You may rarely meet using the regular string-named class fields in Corpuscule tools. Why? Well, the best answer is to avoid naming conflicts. Web components are not React. They won't pack component properties into a separate object this.props. All properties come as class fields. So, to avoid a situation when you want to use property render, but you have a render method that is a heart of your component system, Corpuscule declares all its field names as Symbols. So you are free to use render property along with [render] method, and you are free to create another Symbol named render and use it in the same class. Symbols are unique, and that is their power.

How to use

To work with the Corpuscule project, you have to transpile it using Babel because decorators are not a part of the language yet.

Along with the Babel you have to install @corpuscule/babel-preset that should be used in Babel configuration. This preset contains everything to compile decorators in a way Corpuscule need to work.

Documentation

API documentation is available here.

List of tools

Corpuscule consists of following tools:

  • @corpuscule/context. This package allows creating a context that sends data top-down, from parents to children. Context is DOM-dependent, so using it on different DOM branches with different values you will get different results. It is also a base for many other Corpuscule tools like router or redux.
  • @corpuscule/element. This package provides a set of decorators for creating web components. It is decorator-based analogue for Polymer's LitElement or React.
  • @corpuscule/form. Connector for the 🏁 final-form package that provides Corpuscule solution for forms.
  • @corpuscule/lit-html-renderer. lit-html based renderer for @corpuscule/element. Also includes solution for using custom element class definition as a source for custom element name (MyElement -> my-element) that makes lit-html usage similar to React.
  • @corpuscule/redux. A connector for the Redux library. It is react-redux for Corpuscule.
  • @corpuscule/router. A connector for the Universal Router package, provides Corpuscule solution for routing.
  • @corpuscule/storeon. A connector for the Storeon package, a tiny Redux-like state manager.
  • @corpuscule/styles. A solution for loading CSS stylesheets.
  • @corpuscule/typings. Typescript common typings for the Corpuscule.
  • @corpuscule/utils. This package contains a lot of utilities used in almost all Corpuscule packages. Doesn't have single entrypoint; each util should be loaded separately.

Future

When the static decorator specification reaches stage 3, Corpuscule will be rewritten using it. The current implementation of Corpuscule is done with the basic ideas of the new proposal in mind (that is why it does not use some obvious ideas like a function that creates decorators). It should reduce the number of efforts production code refactoring will take when decorators become a standard.