Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

optimism

Package Overview
Dependencies
Maintainers
1
Versions
72
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

optimism - npm Package Compare versions

Comparing version 0.6.1 to 0.6.2

83

lib/entry.js

@@ -16,3 +16,3 @@ "use strict";

function Entry(fn, args) {
function Entry(fn, key, args) {
this.parents = new Set;

@@ -26,7 +26,12 @@ this.childValues = new Map;

reset(this, fn, args);
reset(this, fn, key, args);
++Entry.count;
}
function reset(entry, fn, args) {
Entry.count = 0;
function reset(entry, fn, key, args) {
entry.fn = fn;
entry.key = key;
entry.args = args;

@@ -38,11 +43,16 @@ entry.value = UNKNOWN_VALUE;

entry.recomputing = false;
// Optional callback that will be invoked when entry.parents becomes
// empty. The Entry object is given as the first parameter. If the
// callback returns true, then this entry can be removed from the graph
// and safely recycled into the entryPool.
entry.reportOrphan = null;
}
Entry.acquire = function (fn, args) {
Entry.acquire = function (fn, key, args) {
var entry = entryPool.pop();
if (entry) {
reset(entry, fn, args);
reset(entry, fn, key, args);
return entry;
}
return new Entry(fn, args);
return new Entry(fn, key, args);
};

@@ -52,3 +62,4 @@

assert(entry.parents.size === 0);
forgetChildren(entry);
assert(entry.childValues.size === 0);
assert(entry.dirtyChildren === null);
entryPool.push(entry);

@@ -65,6 +76,26 @@ }

Ep.recompute = function recompute() {
rememberParent(this);
if (! rememberParent(this) &&
maybeReportOrphan(this)) {
// The recipient of the entry.reportOrphan callback decided to dispose
// of this orphan entry by calling entry.dispos(), which recycles it
// into the entryPool, so we don't need to (and should not) proceed
// with the recomputation.
return;
}
return recomputeIfDirty(this);
};
// If the given entry has a reportOrphan method, and no remaining parents,
// call entry.reportOrphan and return true iff it returns true. The
// reportOrphan function should return true to indicate entry.dispose()
// has been called, and the entry has been removed from any other caches
// (see index.js for the only current example).
function maybeReportOrphan(entry) {
var report = entry.reportOrphan;
return typeof report === "function" &&
entry.parents.size === 0 &&
report(entry) === true;
}
Ep.setDirty = function setDirty() {

@@ -74,8 +105,4 @@ if (this.dirty) return;

this.value = UNKNOWN_VALUE;
// Since we're explicitly setting this.dirty = true, we won't need to
// examine any of our children in recomputeIfDirty, so we can go ahead
// and forget them.
forgetChildren(this);
reportDirty(this);
// We can also go ahead and unsubscribe, since any further dirty
// We can go ahead and unsubscribe here, since any further dirty
// notifications we receive will be redundant, and unsubscribing may

@@ -88,3 +115,3 @@ // free up some resources, e.g. file watchers.

var entry = this;
forgetChildren(entry);
forgetChildren(entry).forEach(maybeReportOrphan);
unsubscribe(entry);

@@ -104,4 +131,4 @@

entry.parents.forEach(function (parent) {
// Causes parent to forget all of its children, including entry.
parent.setDirty();
forgetChild(parent, entry);
});

@@ -168,8 +195,13 @@

function reportCleanChild(entry, child) {
var cv = entry.childValues;
// Must have called rememberChild(child) before calling
// reportCleanChild(parent, child).
assert(entry.childValues.has(child));
assert(cv.has(child));
assert(! mightBeDirty(child));
if (entry.childValues.get(child) !== child.value) {
var childValue = cv.get(child);
if (childValue === UNKNOWN_VALUE) {
cv.set(child, child.value);
} else if (childValue !== child.value) {
entry.setDirty();

@@ -259,3 +291,6 @@ }

forgetChildren(entry);
// Since this recomputation is likely to re-remember some of this
// entry's children, we forget our children here but do not call
// maybeReportOrphan until after the recomputation finishes.
var originalChildren = forgetChildren(entry);

@@ -290,8 +325,18 @@ var local = getLocal();

// Now that we've had a chance to re-remember any children that were
// involved in the recomputation, we can safely report any orphan
// children that remain.
originalChildren.forEach(maybeReportOrphan);
return entry.value;
}
// Removes all children from this entry and returns an array of the
// removed children.
function forgetChildren(entry) {
var children = [];
entry.childValues.forEach(function (value, child) {
forgetChild(entry, child);
children.push(child);
});

@@ -302,2 +347,4 @@

assert(entry.dirtyChildren === null);
return children;
}

@@ -304,0 +351,0 @@

@@ -6,2 +6,3 @@ "use strict";

var Entry = require("./entry.js").Entry;
var getLocal = require("./local.js").get;

@@ -33,2 +34,7 @@ function defaultMakeCacheKey() {

// If this wrapped function is disposable, then its creator does not
// care about its return value, and it should be removed from the cache
// immediately when it no longer has any parents that depend on it.
var disposable = !! options.disposable;
var cache = new Cache({

@@ -41,3 +47,20 @@ max: options.max,

function reportOrphan(entry) {
if (disposable) {
// Triggers the entry.dispose() call above.
cache.delete(entry.key);
return true;
}
}
function optimistic() {
if (disposable && ! getLocal().currentParentEntry) {
// If there's no current parent computation, and this wrapped
// function is disposable (meaning we don't care about entry.value,
// just dependency tracking), then we can short-cut everything else
// in this function, because entry.recompute() is going to recycle
// the entry object without recomputing anything, anyway.
return;
}
var key = options.makeCacheKey.apply(null, arguments);

@@ -55,7 +78,17 @@ if (! key) {

} else {
cache.set(key, entry = Entry.acquire(fn, args));
cache.set(key, entry = Entry.acquire(fn, key, args));
entry.subscribe = options.subscribe;
if (disposable) {
entry.reportOrphan = reportOrphan;
}
}
return entry.recompute();
var value = entry.recompute();
// If options.disposable is truthy, the caller of wrap is telling us
// they don't care about the result of entry.recompute(), so we should
// avoid returning the value, so it won't be accidentally used.
if (! disposable) {
return value;
}
}

@@ -62,0 +95,0 @@

{
"name": "optimism",
"version": "0.6.1",
"version": "0.6.2",
"author": "Ben Newman <ben@benjamn.com>",

@@ -5,0 +5,0 @@ "description": "Composable reactive caching with efficient invalidation.",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc