Security News
Introducing the Socket Python SDK
The initial version of the Socket Python SDK is now on PyPI, enabling developers to more easily interact with the Socket REST API in Python projects.
@sidiousvic/phantom
Advanced tools
npm i @sidiousvic/phantom
export default function Pizza(slices) {
return `
<div id="pizza-box">
<h1 data-phantom="${slices}" id="slices-h1">${slices}</h1>
</div>
`;
}
phantomStore.fire({ type: "EAT_PIZZA" });
In Phantom, components are functions that return HTML template literals.
Template strings allow you to inject dynamic data (including other components) via template literal placeholders ${}
.
export default function phantomComponent() {
const slices
return `
<div id="pizza-box">
<h1 id="slices-h1">🍕</h1>
</div>
`;
}
👻 We recommend the leet-html VSCode extension for HTML string highlighting. |
---|
Use createPhantomStore
to produce your store.
import { createPhantomStore } from "@sidiousvic/phantom";
const data = { slices: ["🍕", "🍕", "🍕"] };
function reducer(state = data, action) {
switch (action.type) {
case "EAT_SLICE": // remove a slice from array
return { ...state, slices: state.slices.slice(0, -1) };
default:
return state;
}
}
const phantomStore = createPhantomStore(reducer);
export default phantomStore;
appear()
Start the Phantom engine by feeding it a component and a store.
import phantom from "@sidiousvic/phantom";
import phantomComponent from "./phantomComponent.js";
import phantomStore from "./phantomStore.js";
const { appear } = phantom(phantomComponent, phantomStore);
appear(); // 3, 2, 1... 💥 initial render!
Phantom will expose the appear
method. 💥
appear
will perform the initial DOM render on call, your UI's first apparition. 👻
Components are cool and all, but what if we want to use dynamic data?
What if we want our UI to react to data changes?
Phantom integrates with a Redux—like store to subscribe the DOM to state updates.
import phantom from "@sidiousvic/phantom";
import phantomComponent from "./phantomComponent.js";
import phantomStore from "./phantomStore.js";
const { appear, data, fire } = phantom(phantomComponent, phantomStore);
appear(); // 3, 2, 1... 🚀 initial render!
data
and fire
are pointers to the Phantom store.
data
to read state from the Phantom store.data
returns the current in—store data.
const { slices } = data();
Data can be passed as arguments to child components.
function phantomComponent() {
const { slices } = data();
return `
${Pizza(slices)}
`;
}
You can use template literal placeholders to inject pieces of state into a component.
export default function Pizza(slices) {
return `
<div id="pizza-box">
<h1 data-phantom="${slices}" id="slices-h1">${slices}</h1>
</div>
`;
}
fire
to dispatch an action and trigger a state update and rerender.An action is an object with a type
key and optional data payload.
fire
takes an action and dispatches it to the phantomStore
, triggering a state change.
Phantom will update the DOM on every fire(action)
.
document.addEventListener("click", eatPizza);
function eatPizza(e) {
if (e.target.id === "slices-h1") {
fire({ type: "EAT_PIZZA" }); // DOM will update
}
}
Phantom can perform DOM differentiation and swap only the nodes whose state has updated. To activate this behavior,
return `<element data-phantom="${yourData}">${yourData}</element>`;
data-phantom
attribute with the piece(s) of state that you want to subscribe to.Phantom will look at at both the data-phantom
and id
attributes in order to compute if a DOM node has to be repainted.
⚠️ If you don't do this, Phantom will repaint the entire DOM on data updates. |
---|
With Phantom, you can write markup in a declarative way ala JSX using raw HTML strings, and inject dynamic data using template literals—staying fully JS native.
No JSX, no complex API, no syntactic hyperglycemia.
Phantom lets you divide your UI into components, abstracting markup into composable functions.
The Phantom engine integrates with a store and subscribes to state updates. It swaps nodes when their data changes.
Frameworks often abstract too much architecture and functionality out of the DOM. They make you yield too much to their way of doing things—events, effects, styling, routing—you have to find the solutions withing their ecosystem.
Phantom only helps with DOM rendering. It's convenient, but close enough to the DOM that you can integrate it with other solutions without using fibers, combiners or adapters of any kind.
* unpacked size of ReactDOM is 3MB. Vue is 2.98MB. Phantom is < 99 kB.
When a component's data changes, Phantom will re—render that node in the DOM by diffing an internal PhantomDOM, a map representation of the DOM.
Yes. Phantom uses the internal PhantomExorciser to sanitize HTML strings before injecting them into the DOM.
Phantom is written and built using Typescript.
npm run build
generates a static build in dist/
.
npm run test
runs the tests located in spec
.
npm run example/<example-name>
runs an example app from examples/
We are always psyched to welcome contributors to Phantom.
Feel free to raise issues, ask questions or fork the project and play with it.
If you want to submit a contribution, please read our
Phantom is maintained regularly by @sidiousvic and @nayelyrodarte.
There are several examples you can run, each furnished with their own devServer
configuration.
Click on one of the images above to be taken to an online sandbox.
Devs who have cloned Phantom may use npm run example/[example name]
and navigate to the url that appears in their terminal.
FAQs
A state—reactive DOM rendering engine for building UIs. 👻
We found that @sidiousvic/phantom 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
The initial version of the Socket Python SDK is now on PyPI, enabling developers to more easily interact with the Socket REST API in Python projects.
Security News
Floating dependency ranges in npm can introduce instability and security risks into your project by allowing unverified or incompatible versions to be installed automatically, leading to unpredictable behavior and potential conflicts.
Security News
A new Rust RFC proposes "Trusted Publishing" for Crates.io, introducing short-lived access tokens via OIDC to improve security and reduce risks associated with long-lived API tokens.