Comparing version 5.2.2 to 5.2.3
{ | ||
"name": "quarx", | ||
"version": "5.2.2", | ||
"version": "5.2.3", | ||
"description": "Simple tiny reactivity engine", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -59,3 +59,3 @@ # 🜉 Quarx | ||
During a single synchronous re-actualization (*hydration*) run of the DAG each computation would be executed at most once. | ||
During a single synchronous re-actualization (*hydration*) run of the DAG each computation would be executed at most once. If the computation throws or if a dependency cycle is detected the `onError` callback is invoked, at most once per hydration. | ||
@@ -62,0 +62,0 @@ ```typescript |
@@ -10,3 +10,3 @@ import { subscribable, toObservable } from './adapters.js'; | ||
const subs = subscribable(evaluate, { name }); | ||
return toObservable(subs, { name: 'result:' + name, equals }); | ||
return toObservable(subs, { name: `(computed ${name})`, equals }); | ||
} |
@@ -36,3 +36,3 @@ const TAG = '@dmaevsky/quarx'; | ||
const onError = options.onError || function(e) { | ||
Quarx.error(`[Quarx]: uncaught exception disposing ${name}:`, e); | ||
Quarx.error('[Quarx ERROR]', 'unhandled @ atom dispose', name, e); | ||
} | ||
@@ -45,5 +45,5 @@ | ||
reportObserved() { | ||
const { invalidate, link } = Quarx.stack[Quarx.stack.length - 1] || {}; | ||
const { invalidate, link, name: fromName } = Quarx.stack[Quarx.stack.length - 1] || {}; | ||
Quarx.debug(`[Quarx]: ${name} observed -> ${!!invalidate}`); | ||
Quarx.debug('[Quarx]', 'observed', name, fromName); | ||
if (!invalidate) return false; | ||
@@ -85,4 +85,4 @@ | ||
reportChanged() { | ||
Quarx.debug(`[Quarx]: ${name} changed`); | ||
const { invalidate, actualize } = Quarx.stack[Quarx.stack.length - 1] || {}; | ||
const { invalidate, actualize, name: fromName } = Quarx.stack[Quarx.stack.length - 1] || {}; | ||
Quarx.debug('[Quarx]', 'changed', name, fromName); | ||
@@ -102,10 +102,18 @@ // Prevent creating self-reference for the running computation | ||
const { name = 'autorun' } = options; | ||
const onError = options.onError || function(e) { | ||
Quarx.error(`[Quarx]: uncaught exception in ${name}:`, e); | ||
const pushError = options.onError || function(e) { | ||
Quarx.error('[Quarx ERROR]', 'unhandled @ computation', name, e); | ||
} | ||
const onError = e => { | ||
// never call the error handler twice in the same hydration | ||
if (seqNoError === Quarx.sequenceNumber) return; | ||
seqNoError = Quarx.sequenceNumber; | ||
pushError(e); | ||
} | ||
computation = tryCatch(computation, onError); | ||
let dependencies = new Set(); | ||
let seqNo = 0, isRunning = false; | ||
let seqNo = 0, seqNoError = 0, isRunning = false; | ||
@@ -115,16 +123,18 @@ const link = dep => dependencies.add(dep); | ||
function invalidate() { | ||
Quarx.debug(`[Quarx]: invalidating ${name}:`, seqNo, Quarx.sequenceNumber); | ||
if (isRunning) return; | ||
Quarx.debug('[Quarx]', 'invalidate', name, seqNo, Quarx.sequenceNumber); | ||
if (Quarx.cleaningUp) { | ||
// No invalidations allowed in dispose callbacks | ||
const message = `[Quarx]: attempt to invalidate ${name} while running the dispose queue`; | ||
Quarx.debug(message); | ||
const args = ['[Quarx ERROR]', 'invalidate at dispose', name]; | ||
Quarx.error(...args); | ||
return onError(new Error(message)); | ||
return onError(new Error(args.join(':'))); | ||
} | ||
if (Quarx.hydrating && seqNo === Quarx.sequenceNumber) { | ||
Quarx.debug(`[Quarx]: Invalidating a freshly hydrated computation ${name} from ${Quarx.stack[0].name} === cycle`); | ||
const args = ['[Quarx ERROR]', 'invalidate hydrated', name, Quarx.stack[Quarx.stack.length - 1].name]; | ||
Quarx.error(...args); | ||
// Calling run greadily so that it can report the cycle | ||
return run(); | ||
return onError(new Error(args.join(':'))); | ||
} | ||
@@ -137,9 +147,9 @@ | ||
function actualize() { | ||
Quarx.debug(`[Quarx]: Actualizing ${name}`, seqNo, Quarx.sequenceNumber); | ||
Quarx.debug('[Quarx]', 'actualize', name, seqNo, Quarx.sequenceNumber); | ||
if (isRunning) { | ||
const trace = [...Quarx.stack.map(({ name }) => name), name]; | ||
const message = `[Quarx]: Circular dependency detected: ${trace.join(' -> ')}`; | ||
Quarx.debug(message); | ||
throw new Error(message); | ||
const args = ['[Quarx ERROR]', 'cycle detected', ...Quarx.stack.map(({ name }) => name), name]; | ||
Quarx.error(...args); | ||
throw new Error(args.join(':')); | ||
} | ||
@@ -168,3 +178,3 @@ | ||
function run() { | ||
Quarx.debug(`[Quarx]: Running ${name}`, Quarx.sequenceNumber); | ||
Quarx.debug('[Quarx]', 'run', name, Quarx.sequenceNumber); | ||
isRunning = true; | ||
@@ -189,3 +199,3 @@ | ||
isRunning = false; | ||
Quarx.debug(`[Quarx]: Finished ${name}`, Quarx.sequenceNumber); | ||
Quarx.debug('[Quarx]', 'finished', name, Quarx.sequenceNumber); | ||
} | ||
@@ -217,3 +227,3 @@ | ||
++Quarx.sequenceNumber; | ||
Quarx.debug(`[Quarx]: Hydration ${Quarx.sequenceNumber}`); | ||
Quarx.debug('[Quarx]', 'hydration start', Quarx.sequenceNumber); | ||
@@ -226,3 +236,3 @@ Quarx.hydrating = true; | ||
Quarx.debug(`[Quarx]: Hydration ${Quarx.sequenceNumber} END`); | ||
Quarx.debug('[Quarx]', 'hydration end', Quarx.sequenceNumber); | ||
} | ||
@@ -229,0 +239,0 @@ |
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
21078
379