Skip to content
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

Refactor internal implementation #104

Merged
merged 15 commits into from
Oct 16, 2019

Conversation

talyssonoc
Copy link
Owner

@talyssonoc talyssonoc commented Oct 8, 2019

This PR includes a huge refactor of all the internal implementation of the lib while keeping the tests basically the same (to guarantee it's an internal-only change).

Why

So, the previous implementation began small because Structure didn't have all the features it has today back then, so it kinda did suffice. When new contributors were added to the projects one of the main things that held them back was to understand how everything interacted. Now that the next major of this project is being developed, I decided it was a good time to refactor everything.

How

Previously everything was attached to the schema object, including the attributes and features (validation, coercion, ...), and everything that wasn't an attribute was a "private" (non-enumerable, symbol-keyed) attribute of it.

Now there are three main classes in the whole architecture: Schema, AttributeDefinitions and AttributeDefinition.

Schema

The schema is still the entry point of most of the features but it now has a field called attributeDefinitions instead of have all of them directly attached to the schema object.

This class is used to manage everything that operates over the whole structure (even if it internally delegates to each of the attribute definitions), including initialization, coercion, dynamic types, validation, and serialization.

AttributeDefinitions

Previously named as "type descriptors" (or "attribute descriptors"), the concept was renamed to "attribute definitions" to avoid confusion with the property descriptors that are passed to Object.defineProperty. This class inherits from array so it's a collection of attribute definitions that can be accessed both as an array (so you can .map, .forEach over each) and it also has each of attributes as a property of it, so you can also do attributeDefinitions.name to get the definition of the attribute name of this given collection.

AttributeDefinition

Each of the items inside a AttributeDefinitions instance is an instance of AttributeDefinition. Like the schema, this is the entry point of everything that is related only to a specific attribute. So this is where the ordering of attributes (base on initialization order) is implemented, dynamic type resolution and coercion.

Descriptors

Previously implemented inside each module, now all the property descriptors are inside a descriptors object that receives the schema and the wrapper class in its constructor. All the links between the features and the instance (or the wrapped class) are created there.

The only features that won't delegate directly to the schema or the attributeDefinitions inside the descriptors are cloning and strict mode because these features aren't implemented in any of these objects.


A whole lot of indirection and confusion were removed in this PR in order to make the code clearer and more welcoming to contributors, and it's also now to add new features since the responsibilities were better separated.

@talyssonoc talyssonoc merged commit b445e11 into structure-2 Oct 16, 2019
@talyssonoc talyssonoc deleted the refactor-internal-implementation branch October 16, 2019 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant