Skip to content

Commit

Permalink
feat: first release - yet to complete
Browse files Browse the repository at this point in the history
  • Loading branch information
Cadienvan committed Mar 4, 2023
0 parents commit 3554f9e
Show file tree
Hide file tree
Showing 14 changed files with 583 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
dist
68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# What Is This?
This is a super simple signal library for browser and Node. It's mostly an experiment which provided good benchmarks and a nice, clean and simple API.

# Installation
```bash
npm install super-simple-signal
```

# Usage
```html
<!-- Load the library from your node_modules or from a CDN -->
<script src="./node_modules/super-simple-signal/index.js"></script>
<script>
const signal = new Signal(0);
signal.subscribe(value => {
console.log(value);
});
window.addEventListener("load", () => {
const s1 = document.getElementById("s1");
signal.attachTo(s1);
});
</script>
<div id="s1"></div>
<button onclick="signal.value++">Click me</button>
```

# API
## Signal
### `new Signal(value)`
Creates a new signal with the given initial value.

### `new Signal(node)`
Creates a new signal which is attached to the given node.

### `new Signal(node, value)`
Creates a new signal which is attached to the given node and has the given initial value.

### `new Signal(node, value, property)`
Creates a new signal which is attached to the given node and has the given initial value. The signal will update the given property of the node. Defaults to `innerHTML`.

### `signal.value`
The current value of the signal.

### `signal.subscribe(callback)`
Subscribes the given callback to the signal. The callback will be called whenever the signal's value changes. The callback will be called with the new value as the first argument.

### `signal.unsubscribe(callback)`
Unsubscribes the given callback from the signal.

### `signal.attachTo(node, property)`
Attaches the signal to the given node. The signal will update the node's given property whenever the signal's value changes. Defaults to `innerHTML`.

### `signal.detachFrom(node)`
Detaches the signal from the given node.

### `signal.copyTo(node, property, keepInSync)`
Copies the signal's value to the given node. This will actually create a new `Signal`. If `keepInSync` is `true`, the new signal will be updated whenever the initial signal changes. Defaults to `false`.



# Considerations
- Currently the library only supports one-way binding. Updating the signal will update the DOM but not the other way around.

# ToDo
- [ ] Add tests
- [ ] Two-way binding
25 changes: 25 additions & 0 deletions examples/attachTo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Signals Demo</title>
</head>
<body>
<div id="s1"></div>
<div id="s2"></div>
<script src="../dist/index.js"></script>
<script>
const s1 = document.getElementById("s1");
const s2 = document.getElementById("s2");

const signal = new Signal(s1);

signal.value = "I am Signal1";

signal.attachTo(s2);
signal.value = "I am Signal2";
</script>
</body>
</html>
37 changes: 37 additions & 0 deletions examples/benchmark.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Signals Demo</title>
</head>
<body>
<div id="s1"></div>
<div id="s2"></div>
<div id="s3"></div>
<script src="../dist/index.js"></script>
<script>
const s1 = document.getElementById("s1");
const s2 = document.getElementById("s2");
const s3 = document.getElementById("s3");

const signal1 = new Signal(s1);
const signal2 = new Signal(s2);
const signal3 = new Signal(s3);

// Continously update the signals with random values
const oneHundredThousandRandomValues = Array.from({ length: 100000 }, () => Math.random());

const perf = new Date().getTime();

for (let value of oneHundredThousandRandomValues) {
signal1.value = value;
signal2.value = value + 1;
signal3.value = value + 2;
}

console.log(`${new Date().getTime() - perf}ms elapsed for 3*100,000 updates`);
</script>
</body>
</html>
26 changes: 26 additions & 0 deletions examples/btn.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Signals Demo</title>
</head>
<body>
<script src="../dist/index.js"></script>
<script>
const signal = new Signal(0);

signal.subscribe(value => {
console.log(value);
});

window.addEventListener("load", () => {
const s1 = document.getElementById("s1");
signal.attachTo(s1);
});
</script>
<div id="s1"></div>
<button onclick="signal.value++">Click me</button>
</body>
</html>
36 changes: 36 additions & 0 deletions examples/computed.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Signals Demo</title>
</head>
<body>
<div id="s1"></div>
<div id="c1"></div>
<script src="../dist/index.js"></script>
<script>
const s1 = document.getElementById("s1");

const signal = new Signal(s1);
const computed = new Computed(signal, (value, oldValue) => {
return value.replace(".", ",");
});

computed.attachTo(document.getElementById("c1"));

signal.subscribe(value => {
console.log("signal", value);
});

computed.subscribe(value => {
console.log("computed", value);
});

setInterval(() => {
signal.value = Math.random().toString();
}, 1000);
</script>
</body>
</html>
31 changes: 31 additions & 0 deletions examples/copyTo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Signals Demo</title>
</head>
<body>
<div id="s1"></div>
<div id="s2"></div>
<script src="../dist/index.js"></script>
<script>
const s1 = document.getElementById("s1");
const s2 = document.getElementById("s2");

const signal = new Signal(s1);

signal.value = "I am Signal1";

signal.copyTo(s2);
signal.value = "I am Signal2 but also Signal1, kept in sync. In 5 secs I'll start to update randomly.";

setTimeout(() => {
setInterval(() => {
signal.value = Math.random();
}, 1000);
}, 5000);
</script>
</body>
</html>
25 changes: 25 additions & 0 deletions examples/subscriber.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Signals Demo</title>
</head>
<body>
<div id="s1"></div>
<script src="../dist/index.js"></script>
<script>
const s1 = document.getElementById("s1");

const signal = new Signal(s1);

signal.subscribe(value => {
console.log(value);
});

signal.value = "I am Signal!";
signal.value = "I am Signal again!";
</script>
</body>
</html>
84 changes: 84 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "super-simple-signal",
"version": "1.0.0",
"description": "A simple signal implementation in TypeScript for the browser and Node.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"start": "tsc -w",
"build": "rm -rf ./dist/* && tsc && rollup ./dist/tmp/index.js --file ./dist/index.js --format iife --name SuperSimpleSignal --sourcemap && rm -rf ./dist/tmp",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"signal",
"typescript",
"browser",
"node",
"event",
"event emitter",
"event dispatcher",
"event bus",
"event system",
"event manager",
"event handler",
"event listener",
"event binding"
],
"author": "Michael Di Prisco <[email protected]>",
"license": "ISC",
"devDependencies": {
"rollup": "^3.18.0",
"typescript": "^4.9.5"
}
}
Loading

0 comments on commit 3554f9e

Please sign in to comment.