@aha-app/react-easy-state
Advanced tools
Comparing version 0.0.3-development to 0.0.4-development
@@ -6,4 +6,4 @@ 'use strict'; | ||
var react = require('react'); | ||
var reactPlatform_cjs = require('./react-platform.cjs'); | ||
var observerUtil = require('@nx-js/observer-util'); | ||
var reactPlatform_cjs = require('./react-platform.cjs'); | ||
@@ -235,26 +235,43 @@ function _classCallCheck(instance, Constructor) { | ||
}).filter(observerUtil.isObservable).map(observerUtil.raw); | ||
} // We batch all updates to the view until the end of the current task. This | ||
// is to prevent excessive rendering in situations where updates can occur | ||
// outside of React's built-in batching. e.g. after resolving a promise, | ||
// in a setTimeout callback, in an event handler. | ||
var batchesPending = {}; | ||
var taskPending = false; | ||
var viewIndexCounter = 0; | ||
function batchSetState(viewIndex, fn) { | ||
batchesPending[viewIndex] = fn; | ||
if (!taskPending) { | ||
console.log('Batching setState'); | ||
taskPending = true; | ||
queueMicrotask(function () { | ||
console.log('Running setState'); | ||
var batchesToRun = batchesPending; | ||
taskPending = false; | ||
batchesPending = {}; | ||
reactPlatform_cjs.unstable_batchedUpdates(function () { | ||
return Object.values(batchesToRun).forEach(function (fn) { | ||
return fn(); | ||
}); | ||
}); | ||
}); | ||
} else { | ||
console.log('Already batched setState'); | ||
} | ||
} | ||
function clearBatch(viewIndex) { | ||
delete batchesPending[viewIndex]; | ||
} | ||
function view(Comp) { | ||
var viewIndex = viewIndexCounter++; | ||
var isStatelessComp = !(Comp.prototype && Comp.prototype.isReactComponent); | ||
var ReactiveComp; | ||
var batchPending = false; | ||
function batchSetState(fn) { | ||
if (!batchPending) { | ||
console.log('Batching setState'); | ||
batchPending = true; // TODO: this should be a microtask so that we don't wait for other events | ||
// before executing. jest is not working with queueMicrotask. | ||
queueMicrotask(function () { | ||
// setTimeout(() => { | ||
console.log('Running setState'); | ||
batchPending = false; | ||
fn(); | ||
}); | ||
} else { | ||
console.log('Already batched setState'); | ||
} | ||
} | ||
if (isStatelessComp && hasHooks) { | ||
@@ -273,3 +290,3 @@ // use a hook based reactive wrapper when we can | ||
scheduler: function scheduler() { | ||
return batchSetState(function () { | ||
return batchSetState(viewIndex, function () { | ||
return setState({}); | ||
@@ -286,3 +303,4 @@ }); | ||
return function () { | ||
return observerUtil.unobserve(render); | ||
clearBatch(viewIndex); | ||
observerUtil.unobserve(render); | ||
}; | ||
@@ -319,3 +337,3 @@ }, []); // the isInsideFunctionComponent flag is used to toggle `store` behavior | ||
scheduler: function scheduler() { | ||
return batchSetState(function () { | ||
return batchSetState(viewIndex, function () { | ||
return _this.setState({}); | ||
@@ -372,4 +390,5 @@ }); | ||
_get(_getPrototypeOf(ReactiveClassComp.prototype), "componentWillUnmount", this).call(this); | ||
} // clean up memory used by Easy State | ||
} | ||
clearBatch(viewIndex); // clean up memory used by Easy State | ||
@@ -376,0 +395,0 @@ observerUtil.unobserve(this.render); |
@@ -6,4 +6,4 @@ 'use strict'; | ||
var react = require('react'); | ||
var reactPlatform_cjs = require('./react-platform.cjs'); | ||
var observerUtil = require('@nx-js/observer-util'); | ||
var reactPlatform_cjs = require('./react-platform.cjs'); | ||
@@ -23,26 +23,39 @@ const hasHooks = typeof react.useState === 'function'; | ||
return Object.keys(component).map(key => component[key]).filter(observerUtil.isObservable).map(observerUtil.raw); | ||
} // We batch all updates to the view until the end of the current task. This | ||
// is to prevent excessive rendering in situations where updates can occur | ||
// outside of React's built-in batching. e.g. after resolving a promise, | ||
// in a setTimeout callback, in an event handler. | ||
let batchesPending = {}; | ||
let taskPending = false; | ||
let viewIndexCounter = 0; | ||
function batchSetState(viewIndex, fn) { | ||
batchesPending[viewIndex] = fn; | ||
if (!taskPending) { | ||
console.log('Batching setState'); | ||
taskPending = true; | ||
queueMicrotask(() => { | ||
console.log('Running setState'); | ||
const batchesToRun = batchesPending; | ||
taskPending = false; | ||
batchesPending = {}; | ||
reactPlatform_cjs.unstable_batchedUpdates(() => Object.values(batchesToRun).forEach(fn => fn())); | ||
}); | ||
} else { | ||
console.log('Already batched setState'); | ||
} | ||
} | ||
function clearBatch(viewIndex) { | ||
delete batchesPending[viewIndex]; | ||
} | ||
function view(Comp) { | ||
const viewIndex = viewIndexCounter++; | ||
const isStatelessComp = !(Comp.prototype && Comp.prototype.isReactComponent); | ||
let ReactiveComp; | ||
let batchPending = false; | ||
function batchSetState(fn) { | ||
if (!batchPending) { | ||
console.log('Batching setState'); | ||
batchPending = true; // TODO: this should be a microtask so that we don't wait for other events | ||
// before executing. jest is not working with queueMicrotask. | ||
queueMicrotask(() => { | ||
// setTimeout(() => { | ||
console.log('Running setState'); | ||
batchPending = false; | ||
fn(); | ||
}); | ||
} else { | ||
console.log('Already batched setState'); | ||
} | ||
} | ||
if (isStatelessComp && hasHooks) { | ||
@@ -56,3 +69,3 @@ // use a hook based reactive wrapper when we can | ||
const render = react.useMemo(() => observerUtil.observe(Comp, { | ||
scheduler: () => batchSetState(() => setState({})), | ||
scheduler: () => batchSetState(viewIndex, () => setState({})), | ||
lazy: true | ||
@@ -64,3 +77,6 @@ }), // Adding the original Comp here is necessary to make React Hot Reload work | ||
react.useEffect(() => { | ||
return () => observerUtil.unobserve(render); | ||
return () => { | ||
clearBatch(viewIndex); | ||
observerUtil.unobserve(render); | ||
}; | ||
}, []); // the isInsideFunctionComponent flag is used to toggle `store` behavior | ||
@@ -89,3 +105,3 @@ // based on where it was called from | ||
this.render = observerUtil.observe(this.render, { | ||
scheduler: () => batchSetState(() => this.setState({})), | ||
scheduler: () => batchSetState(viewIndex, () => this.setState({})), | ||
lazy: true | ||
@@ -149,4 +165,5 @@ }); | ||
super.componentWillUnmount(); | ||
} // clean up memory used by Easy State | ||
} | ||
clearBatch(viewIndex); // clean up memory used by Easy State | ||
@@ -153,0 +170,0 @@ observerUtil.unobserve(this.render); |
import { useState, memo, useMemo, useEffect, Component } from 'react'; | ||
import { unstable_batchedUpdates } from './react-platform'; | ||
import { observe, unobserve, isObservable, raw, observable } from '@nx-js/observer-util'; | ||
export { unobserve as clearEffect } from '@nx-js/observer-util'; | ||
import { unstable_batchedUpdates } from './react-platform'; | ||
@@ -231,26 +231,43 @@ function _classCallCheck(instance, Constructor) { | ||
}).filter(isObservable).map(raw); | ||
} // We batch all updates to the view until the end of the current task. This | ||
// is to prevent excessive rendering in situations where updates can occur | ||
// outside of React's built-in batching. e.g. after resolving a promise, | ||
// in a setTimeout callback, in an event handler. | ||
var batchesPending = {}; | ||
var taskPending = false; | ||
var viewIndexCounter = 0; | ||
function batchSetState(viewIndex, fn) { | ||
batchesPending[viewIndex] = fn; | ||
if (!taskPending) { | ||
console.log('Batching setState'); | ||
taskPending = true; | ||
queueMicrotask(function () { | ||
console.log('Running setState'); | ||
var batchesToRun = batchesPending; | ||
taskPending = false; | ||
batchesPending = {}; | ||
unstable_batchedUpdates(function () { | ||
return Object.values(batchesToRun).forEach(function (fn) { | ||
return fn(); | ||
}); | ||
}); | ||
}); | ||
} else { | ||
console.log('Already batched setState'); | ||
} | ||
} | ||
function clearBatch(viewIndex) { | ||
delete batchesPending[viewIndex]; | ||
} | ||
function view(Comp) { | ||
var viewIndex = viewIndexCounter++; | ||
var isStatelessComp = !(Comp.prototype && Comp.prototype.isReactComponent); | ||
var ReactiveComp; | ||
var batchPending = false; | ||
function batchSetState(fn) { | ||
if (!batchPending) { | ||
console.log('Batching setState'); | ||
batchPending = true; // TODO: this should be a microtask so that we don't wait for other events | ||
// before executing. jest is not working with queueMicrotask. | ||
queueMicrotask(function () { | ||
// setTimeout(() => { | ||
console.log('Running setState'); | ||
batchPending = false; | ||
fn(); | ||
}); | ||
} else { | ||
console.log('Already batched setState'); | ||
} | ||
} | ||
if (isStatelessComp && hasHooks) { | ||
@@ -269,3 +286,3 @@ // use a hook based reactive wrapper when we can | ||
scheduler: function scheduler() { | ||
return batchSetState(function () { | ||
return batchSetState(viewIndex, function () { | ||
return setState({}); | ||
@@ -282,3 +299,4 @@ }); | ||
return function () { | ||
return unobserve(render); | ||
clearBatch(viewIndex); | ||
unobserve(render); | ||
}; | ||
@@ -315,3 +333,3 @@ }, []); // the isInsideFunctionComponent flag is used to toggle `store` behavior | ||
scheduler: function scheduler() { | ||
return batchSetState(function () { | ||
return batchSetState(viewIndex, function () { | ||
return _this.setState({}); | ||
@@ -368,4 +386,5 @@ }); | ||
_get(_getPrototypeOf(ReactiveClassComp.prototype), "componentWillUnmount", this).call(this); | ||
} // clean up memory used by Easy State | ||
} | ||
clearBatch(viewIndex); // clean up memory used by Easy State | ||
@@ -372,0 +391,0 @@ unobserve(this.render); |
import { useState, memo, useMemo, useEffect, Component } from 'react'; | ||
import { unstable_batchedUpdates } from './react-platform'; | ||
import { observe, unobserve, isObservable, raw, observable } from '@nx-js/observer-util'; | ||
export { unobserve as clearEffect } from '@nx-js/observer-util'; | ||
import { unstable_batchedUpdates } from './react-platform'; | ||
@@ -19,26 +19,39 @@ const hasHooks = typeof useState === 'function'; | ||
return Object.keys(component).map(key => component[key]).filter(isObservable).map(raw); | ||
} // We batch all updates to the view until the end of the current task. This | ||
// is to prevent excessive rendering in situations where updates can occur | ||
// outside of React's built-in batching. e.g. after resolving a promise, | ||
// in a setTimeout callback, in an event handler. | ||
let batchesPending = {}; | ||
let taskPending = false; | ||
let viewIndexCounter = 0; | ||
function batchSetState(viewIndex, fn) { | ||
batchesPending[viewIndex] = fn; | ||
if (!taskPending) { | ||
console.log('Batching setState'); | ||
taskPending = true; | ||
queueMicrotask(() => { | ||
console.log('Running setState'); | ||
const batchesToRun = batchesPending; | ||
taskPending = false; | ||
batchesPending = {}; | ||
unstable_batchedUpdates(() => Object.values(batchesToRun).forEach(fn => fn())); | ||
}); | ||
} else { | ||
console.log('Already batched setState'); | ||
} | ||
} | ||
function clearBatch(viewIndex) { | ||
delete batchesPending[viewIndex]; | ||
} | ||
function view(Comp) { | ||
const viewIndex = viewIndexCounter++; | ||
const isStatelessComp = !(Comp.prototype && Comp.prototype.isReactComponent); | ||
let ReactiveComp; | ||
let batchPending = false; | ||
function batchSetState(fn) { | ||
if (!batchPending) { | ||
console.log('Batching setState'); | ||
batchPending = true; // TODO: this should be a microtask so that we don't wait for other events | ||
// before executing. jest is not working with queueMicrotask. | ||
queueMicrotask(() => { | ||
// setTimeout(() => { | ||
console.log('Running setState'); | ||
batchPending = false; | ||
fn(); | ||
}); | ||
} else { | ||
console.log('Already batched setState'); | ||
} | ||
} | ||
if (isStatelessComp && hasHooks) { | ||
@@ -52,3 +65,3 @@ // use a hook based reactive wrapper when we can | ||
const render = useMemo(() => observe(Comp, { | ||
scheduler: () => batchSetState(() => setState({})), | ||
scheduler: () => batchSetState(viewIndex, () => setState({})), | ||
lazy: true | ||
@@ -60,3 +73,6 @@ }), // Adding the original Comp here is necessary to make React Hot Reload work | ||
useEffect(() => { | ||
return () => unobserve(render); | ||
return () => { | ||
clearBatch(viewIndex); | ||
unobserve(render); | ||
}; | ||
}, []); // the isInsideFunctionComponent flag is used to toggle `store` behavior | ||
@@ -85,3 +101,3 @@ // based on where it was called from | ||
this.render = observe(this.render, { | ||
scheduler: () => batchSetState(() => this.setState({})), | ||
scheduler: () => batchSetState(viewIndex, () => this.setState({})), | ||
lazy: true | ||
@@ -145,4 +161,5 @@ }); | ||
super.componentWillUnmount(); | ||
} // clean up memory used by Easy State | ||
} | ||
clearBatch(viewIndex); // clean up memory used by Easy State | ||
@@ -149,0 +166,0 @@ unobserve(this.render); |
{ | ||
"name": "@aha-app/react-easy-state", | ||
"version": "0.0.3-development", | ||
"version": "0.0.4-development", | ||
"description": "React state management with a minimal API. Made with ES6 Proxies.", | ||
@@ -14,3 +14,3 @@ "main": "dist/cjs.es6.js", | ||
"test-native": "NATIVE=true jest --config ./jest.native.json --silent", | ||
"test-web": "jest --config ./jest.web.json --silent", | ||
"test-web": "jest --config ./jest.web.json --verbose=false", | ||
"test-web-no-hook": "NOHOOK=true jest --config ./jest.no-hook.json --silent", | ||
@@ -17,0 +17,0 @@ "test": "npm run test-web && npm run test-web-no-hook && npm run test-native", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
196775
1880