Skip to content

Instantly share code, notes, and snippets.

@AnandPilania
Created July 22, 2024 03:46
Show Gist options
  • Save AnandPilania/cb047d298e9fc95ae273556c43444ede to your computer and use it in GitHub Desktop.
Save AnandPilania/cb047d298e9fc95ae273556c43444ede to your computer and use it in GitHub Desktop.
SolidJS implementation of signals from scratch using the Pub-Sub pattern.
import { createSignal, createEffect } from "./signal.js";
const [name, setName] = createSignal("Reyansh");
const [age, setAge] = createSignal(2.5);
// Effects automatically subscribes to signals used within
createEffect(() => {
// Runs whenever the count changes
console.log(`Name: ${name()}, Age: ${age()}`);
});
setName("Old Reyansh");
setTimeout(() => {
setAge(3);
}, 2000);
/**
* Open Console on the preview to see the output
*/
class Signal {
constructor(value) {
this.value = value;
this.subscribers = [];
}
getValue() {
return this.value;
}
setValue(newValue) {
this.value = newValue;
this.emit();
}
emit() {
this.subscribers.forEach((subscriber) => subscriber(this.value));
}
subscribe(callback) {
this.subscribers.push(callback);
}
}
let effectCallback = null;
export const createSignal = (value) => {
const signal = new Signal(value);
return [
function value() {
// when true this means, the value() is fetched from within the effect callback
// we should register this effect callback when value changes
if (effectCallback) {
signal.subscribe(effectCallback);
}
return signal.getValue();
},
function setValue(newVal) {
signal.setValue(newVal);
},
];
};
export const createEffect = (callback) => {
// Exposes the callback it's going to execute
effectCallback = callback;
// callback should execute immediately
// Executing this callback may trigger multiple value() calls
// So expect the value() method in createSignal to subscribe to this callback after this executes
callback();
// Resets the callback
effectCallback = null;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment