Created
July 22, 2024 03:46
-
-
Save AnandPilania/cb047d298e9fc95ae273556c43444ede to your computer and use it in GitHub Desktop.
SolidJS implementation of signals from scratch using the Pub-Sub pattern.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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