@bikeshaving/crank
Advanced tools
Comparing version 0.3.10 to 0.3.11
# Changelog | ||
## [0.3.11] - 2021-05-11 | ||
### Fixed | ||
- Crank will now always create new elements for internal nodes to prevent subtle aliasing bugs (#198). | ||
- Fixed an edge case where a scheduled refresh failed to update the component when the produced child was a component (#199). | ||
- Optimized multiple components scheduling a refresh synchronously (#155). | ||
## [0.3.10] - 2021-04-30 | ||
@@ -9,3 +14,4 @@ ### Fixed | ||
## [0.3.8] - 2020-12-27 | ||
Various performance improvements. | ||
### Fixed | ||
- Various performance improvements. | ||
### Changed | ||
@@ -12,0 +18,0 @@ - `create()` and `patch()` calls have been moved to a pre-order traversal of the tree. |
@@ -88,2 +88,4 @@ 'use strict'; | ||
* interop between elements and renderers of different versions of Crank. | ||
* | ||
* TODO: Consider deleting this flag because we’re not using it anymore. | ||
*/ | ||
@@ -613,7 +615,5 @@ const IsInUse = 1 << 0; | ||
// TODO: implement Raw element parse caching | ||
if (oldChild !== newChild) { | ||
oldChild.props = newChild.props; | ||
oldChild.ref = newChild.ref; | ||
newChild = oldChild; | ||
} | ||
oldChild.props = newChild.props; | ||
oldChild.ref = newChild.ref; | ||
newChild = oldChild; | ||
value = update(renderer, root, host, ctx, scope, newChild); | ||
@@ -638,5 +638,3 @@ } | ||
else { | ||
if (newChild._f & IsInUse) { | ||
newChild = cloneElement(newChild); | ||
} | ||
newChild = new Element(newChild.tag, newChild.props, newChild.key, newChild.ref); | ||
value = mount(renderer, root, host, ctx, scope, newChild); | ||
@@ -829,2 +827,10 @@ if (isPromiseLike(value)) { | ||
const IsAsyncGen = 1 << 7; | ||
/** | ||
* A flag which is set while schedule callbacks are called. | ||
*/ | ||
const IsScheduling = 1 << 8; | ||
/** | ||
* A flag which is set when a schedule callback calls refresh. | ||
*/ | ||
const IsSchedulingRefresh = 1 << 9; | ||
const provisionMaps = new WeakMap(); | ||
@@ -1390,3 +1396,7 @@ const scheduleMap = new WeakMap(); | ||
} | ||
if (!(ctx._f & IsUpdating)) { | ||
if (ctx._f & IsScheduling) { | ||
ctx._f |= IsSchedulingRefresh; | ||
} | ||
else if (!(ctx._f & IsUpdating)) { | ||
// Rearrange the host. | ||
const listeners = getListeners(ctx._pa, ctx._ho); | ||
@@ -1415,16 +1425,28 @@ if (listeners.length) { | ||
} | ||
ctx._f &= ~IsUpdating; | ||
const value = unwrap(values); | ||
let value = unwrap(values); | ||
const callbacks = scheduleMap.get(ctx); | ||
if (callbacks && callbacks.size) { | ||
const callbacks1 = Array.from(callbacks); | ||
// We must clear the set of callbacks before calling them, because a | ||
// callback which refreshes the component would otherwise cause a stack | ||
// overflow. | ||
const callbacks1 = Array.from(callbacks); | ||
callbacks.clear(); | ||
const value1 = ctx._re.read(value); | ||
ctx._f |= IsScheduling; | ||
for (const callback of callbacks1) { | ||
callback(value1); | ||
try { | ||
callback(value1); | ||
} | ||
catch (err) { | ||
// TODO: handle schedule callback errors in a better way. | ||
console.error(err); | ||
} | ||
} | ||
ctx._f &= ~IsScheduling; | ||
if (ctx._f & IsSchedulingRefresh) { | ||
ctx._f &= ~IsSchedulingRefresh; | ||
value = getValue(ctx._el); | ||
} | ||
} | ||
ctx._f &= ~IsUpdating; | ||
return value; | ||
@@ -1438,7 +1460,14 @@ } | ||
if (callbacks && callbacks.size) { | ||
const callbacks1 = Array.from(callbacks); | ||
callbacks.clear(); | ||
const value = ctx._re.read(getValue(ctx._el)); | ||
for (const cleanup of callbacks) { | ||
cleanup(value); | ||
for (const callback of callbacks1) { | ||
try { | ||
callback(value); | ||
} | ||
catch (err) { | ||
// TODO: handle cleanup callback errors in a better way. | ||
console.error(err); | ||
} | ||
} | ||
callbacks.clear(); | ||
} | ||
@@ -1445,0 +1474,0 @@ if (!(ctx._f & IsDone)) { |
61
crank.js
@@ -85,2 +85,4 @@ /// <reference types="./crank.d.ts" /> | ||
* interop between elements and renderers of different versions of Crank. | ||
* | ||
* TODO: Consider deleting this flag because we’re not using it anymore. | ||
*/ | ||
@@ -610,7 +612,5 @@ const IsInUse = 1 << 0; | ||
// TODO: implement Raw element parse caching | ||
if (oldChild !== newChild) { | ||
oldChild.props = newChild.props; | ||
oldChild.ref = newChild.ref; | ||
newChild = oldChild; | ||
} | ||
oldChild.props = newChild.props; | ||
oldChild.ref = newChild.ref; | ||
newChild = oldChild; | ||
value = update(renderer, root, host, ctx, scope, newChild); | ||
@@ -635,5 +635,3 @@ } | ||
else { | ||
if (newChild._f & IsInUse) { | ||
newChild = cloneElement(newChild); | ||
} | ||
newChild = new Element(newChild.tag, newChild.props, newChild.key, newChild.ref); | ||
value = mount(renderer, root, host, ctx, scope, newChild); | ||
@@ -826,2 +824,10 @@ if (isPromiseLike(value)) { | ||
const IsAsyncGen = 1 << 7; | ||
/** | ||
* A flag which is set while schedule callbacks are called. | ||
*/ | ||
const IsScheduling = 1 << 8; | ||
/** | ||
* A flag which is set when a schedule callback calls refresh. | ||
*/ | ||
const IsSchedulingRefresh = 1 << 9; | ||
const provisionMaps = new WeakMap(); | ||
@@ -1387,3 +1393,7 @@ const scheduleMap = new WeakMap(); | ||
} | ||
if (!(ctx._f & IsUpdating)) { | ||
if (ctx._f & IsScheduling) { | ||
ctx._f |= IsSchedulingRefresh; | ||
} | ||
else if (!(ctx._f & IsUpdating)) { | ||
// Rearrange the host. | ||
const listeners = getListeners(ctx._pa, ctx._ho); | ||
@@ -1412,16 +1422,28 @@ if (listeners.length) { | ||
} | ||
ctx._f &= ~IsUpdating; | ||
const value = unwrap(values); | ||
let value = unwrap(values); | ||
const callbacks = scheduleMap.get(ctx); | ||
if (callbacks && callbacks.size) { | ||
const callbacks1 = Array.from(callbacks); | ||
// We must clear the set of callbacks before calling them, because a | ||
// callback which refreshes the component would otherwise cause a stack | ||
// overflow. | ||
const callbacks1 = Array.from(callbacks); | ||
callbacks.clear(); | ||
const value1 = ctx._re.read(value); | ||
ctx._f |= IsScheduling; | ||
for (const callback of callbacks1) { | ||
callback(value1); | ||
try { | ||
callback(value1); | ||
} | ||
catch (err) { | ||
// TODO: handle schedule callback errors in a better way. | ||
console.error(err); | ||
} | ||
} | ||
ctx._f &= ~IsScheduling; | ||
if (ctx._f & IsSchedulingRefresh) { | ||
ctx._f &= ~IsSchedulingRefresh; | ||
value = getValue(ctx._el); | ||
} | ||
} | ||
ctx._f &= ~IsUpdating; | ||
return value; | ||
@@ -1435,7 +1457,14 @@ } | ||
if (callbacks && callbacks.size) { | ||
const callbacks1 = Array.from(callbacks); | ||
callbacks.clear(); | ||
const value = ctx._re.read(getValue(ctx._el)); | ||
for (const cleanup of callbacks) { | ||
cleanup(value); | ||
for (const callback of callbacks1) { | ||
try { | ||
callback(value); | ||
} | ||
catch (err) { | ||
// TODO: handle cleanup callback errors in a better way. | ||
console.error(err); | ||
} | ||
} | ||
callbacks.clear(); | ||
} | ||
@@ -1442,0 +1471,0 @@ if (!(ctx._f & IsDone)) { |
{ | ||
"name": "@bikeshaving/crank", | ||
"version": "0.3.10", | ||
"version": "0.3.11", | ||
"description": "Write JSX-driven components with functions, promises and generators.", | ||
@@ -5,0 +5,0 @@ "homepage": "https://crank.js.org", |
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 too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
666918
7645