Skip to content

Instantly share code, notes, and snippets.

@athif23
Forked from getify/1.js
Created October 30, 2018 00:16
Show Gist options
  • Save athif23/5b604d945dc1473d0376a5ea21cb4fc3 to your computer and use it in GitHub Desktop.
Save athif23/5b604d945dc1473d0376a5ea21cb4fc3 to your computer and use it in GitHub Desktop.
experiment: implementing something like React's new "useState()" hook in stand-alone functions
"use strict";
[foo,bar] = TNG(foo,bar);
function foo(origX,origY) {
var [x,setX] = useState(origX);
var [y,setY] = useState(origY);
console.log(`foo: ${x} ${y}`);
setX( x * 2 );
setY( bar(y) );
return origX;
}
function bar(curY) {
var [z,setZ] = useState(curY + 1);
console.log(`bar: ${z}`);
z = z * curY;
setZ( z );
return z;
}
foo(3,9);
// foo: 3 9
// bar: 10
foo();
// foo: 6 90
// bar: 90
foo();
// foo: 12 8100
// bar: 8100
var { TNG, useState } = (function def(){
"use strict";
var buckets = new WeakMap();
var currentBucket = [];
return { TNG, useState };
// ******************
function TNG(...fns) {
fns = fns.map(function mapper(fn){
return function tngf(...args) {
if (buckets.has(tngf)) {
let bucket = buckets.get(tngf);
bucket.nextIdx = 0;
}
currentBucket.push(tngf);
try {
return fn.apply(this,args);
}
finally {
currentBucket.pop();
}
};
});
if (fns.length < 2) return fns[0];
return fns;
}
function useState(defVal) {
if (currentBucket.length > 0) {
let tngf = currentBucket[currentBucket.length - 1];
let bucket;
if (!buckets.has(tngf)) {
bucket = { nextIdx: 0, slots: [], };
buckets.set(tngf,bucket);
}
bucket = buckets.get(tngf);
if (!(bucket.nextIdx in bucket.slots)) {
let slot = [ defVal, function updateSlot(v){ slot[0] = v; } ];
bucket.slots[bucket.nextIdx] = slot;
}
return [...bucket.slots[bucket.nextIdx++]];
}
else {
throw new Error("Only use useState() inside TNG-wrapped functions.");
}
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment