Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
@ivy-js/trax
Advanced tools
Trax is a state management library that helps structuring and consuming data in typescript applications.
Most applications - in particular User Interfaces - use the MVC pattern to logically split the code in three entities: the data (aka. the Model - or state), the User Interface (aka. the View) and the actions (aka. the Controller).
These entities should ideally interact as follows:
In practice this sequence is not so simple to implement as data changes cannot be observed in JS applications. Besides, performance optimizations and scalability require to minimize the number of operations to update a view - so application developers (or UI frameworks) need to know precisely what particular piece of data has changed to produce efficient UIs.
This is where state management libraries step in as their goal is to offer the following possibilities:
Many popular state management libraries (such as redux, immerJS or immutableJS) have decided to use immutability as a way to solve problem #2 (if you are not familiar with immutability, it means that an object cannot be changed once created - so that applying changes to an object requires creating a new object instance (like for strings in JavaScript): so if data objects are immutable, they just need to be compared to know if they changed). The problem with immutability is that in a JS environment it imposes very painful, fragile and heavy coding patterns.
This is why the core idea behind trax is to use a versioning system instead of immutability.
Here is how the previous MVC sequence is executed in a trax environment (note: more optimized versions can be implemented, but this to give the general idea).
The previous explanation may give the impression that using trax is complex. It is actually the opposite. From the developer's point of view, here is what it looks like.
First, the trax objects have to be defined. Let's imagine for instance that you want to model a list of 'todo' tasks - here is what you would need to write:
import { Data } from 'trax';
@Data class TodoTask {
description = "";
done = false;
}
@Data class TodoList {
name: string;
tasks: TodoTask[];
}
As you can see, defining trax objects consists in declaring value object classes annotated with the @Data decorator. This decorator is used at build time by trax to rewrite the class code and add meta-data information (trax provides rollup and webpack plugins for this).
Then you will need to instantiate your data objects. This can be done either manually:
const ls = new TaskList();
ls.name = "dev todos";
let t = new TodoTask();
t.description = "assess trax";
ls.push(t);
or by creating the data object from a JSON object:
import { create } from 'trax';
const ls = create(TaskList, {name: "dev todos", tasks:[{ description:"assess trax" }]});
At this point, the ls object is created and can be consumed immediately.
As an example, let's imagine that we want do display the task list in the console:
function render(tl: TaskList) {
console.log(`${tl.name}:`);
tl.tasks.forEach((task:TodoTask, idx:number) => {
console.log(`${idx+1}. ${task.description} ${task.done? '(done!)' : ''}`);
});
}
render(ls);
The console output should look like this:
dev todos:
1. assess trax
Now, if you want the console to keep constantly in sync with the ls data, you simply need to watch the ls instance and call render again anytime a change is reported:
import { watch } from 'trax';
watch(ls, () => render(ls)); // render will be called anytime a change occurs in ls or its children
After that, running code like this:
ls.tasks[0].done = true;
will automatically trigger an asynchronous render call that will be displayed in the console:
dev todos:
1. assess trax (done!)
As the watchers are called asynchronously (through the micro task), multiple synchronous changes will result in only one watcher call:
// the following set of operations will only trigger one watcher call
ls.tasks.push(create(TodoTask, {description: "check micro-tasks"}));
ls.tasks.name = "todo - important";
Note: a more complete example based on the TodoMVC application is available here
Full api documentation here
Syntax cheat-sheet here
FAQs
Trackable data objects
The npm package @ivy-js/trax receives a total of 0 weekly downloads. As such, @ivy-js/trax popularity was classified as not popular.
We found that @ivy-js/trax demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.