mobx 7.0.4 → 7.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -816,6 +816,19 @@ function createAutoAnnotation(options) {
816
816
  extend_
817
817
  };
818
818
  }
819
+ // The auto annotation only depends on `deep` and `autoBind`, so share one instance per combination
820
+ // instead of allocating one for every object created with options
821
+ const autoAnnotations = [autoAnnotation];
822
+ function getAutoAnnotation(options) {
823
+ var _autoAnnotations$idx;
824
+ const deep = options.deep !== false;
825
+ const autoBind = !!options.autoBind;
826
+ const idx = (deep ? 0 : 1) | (autoBind ? 2 : 0);
827
+ return (_autoAnnotations$idx = autoAnnotations[idx]) != null ? _autoAnnotations$idx : autoAnnotations[idx] = createAutoAnnotation({
828
+ deep,
829
+ autoBind
830
+ });
831
+ }
819
832
  function make_$1(adm, key, descriptor, source) {
820
833
  var _this$options_3, _this$options_4;
821
834
  // getter -> computed
@@ -932,7 +945,7 @@ function getEnhancerFromOptions(options) {
932
945
  }
933
946
  function getAnnotationFromOptions(options) {
934
947
  var _options$defaultDecor;
935
- return options ? (_options$defaultDecor = options.defaultDecorator) != null ? _options$defaultDecor : createAutoAnnotation(options) : undefined;
948
+ return options ? (_options$defaultDecor = options.defaultDecorator) != null ? _options$defaultDecor : getAutoAnnotation(options) : undefined;
936
949
  }
937
950
  function getEnhancerFromAnnotation(annotation) {
938
951
  var _annotation$options_$, _annotation$options_;
@@ -1984,34 +1997,41 @@ function endBatch() {
1984
1997
  // the nested call instead of recursing; the outer loop re-reads list.length on
1985
1998
  // every iteration, so it picks up anything the nested dispose() pushes onto the
1986
1999
  // same pendingUnobservations array.
1987
- if (!globalState.isRunningUnobservations) {
1988
- globalState.isRunningUnobservations = true;
1989
- try {
1990
- const list = globalState.pendingUnobservations;
1991
- for (let i = 0; i < list.length; i++) {
1992
- const observable = list[i];
1993
- observable.isPendingUnobservation = false;
1994
- if (!observable.observers_ || observable.observers_.size === 0) {
1995
- if (observable.isBeingObserved) {
1996
- // if this observable had reactive observers, trigger the hooks
1997
- observable.isBeingObserved = false;
1998
- observable.onBUO();
1999
- }
2000
- if (observable instanceof ComputedValue) {
2001
- // computed values are automatically teared down when the last observer leaves
2002
- // this process happens recursively, this computed might be the last observabe of another, etc..
2003
- observable.suspend_();
2004
- }
2005
- }
2000
+ if (!globalState.isRunningUnobservations && globalState.pendingUnobservations.length > 0) {
2001
+ runPendingUnobservations();
2002
+ }
2003
+ }
2004
+ }
2005
+ // Only called when there is something to unobserve, so the common endBatch() skips the
2006
+ // try/finally and the pendingUnobservations reallocation entirely
2007
+ function runPendingUnobservations() {
2008
+ globalState.isRunningUnobservations = true;
2009
+ try {
2010
+ const list = globalState.pendingUnobservations;
2011
+ for (let i = 0; i < list.length; i++) {
2012
+ const observable = list[i];
2013
+ observable.isPendingUnobservation = false;
2014
+ if (!observable.observers_ || observable.observers_.size === 0) {
2015
+ // release the empty Set so unobserved atoms don't keep paying for it
2016
+ observable.observers_ = null;
2017
+ if (observable.isBeingObserved) {
2018
+ // if this observable had reactive observers, trigger the hooks
2019
+ observable.isBeingObserved = false;
2020
+ observable.onBUO();
2021
+ }
2022
+ if (observable instanceof ComputedValue) {
2023
+ // computed values are automatically teared down when the last observer leaves
2024
+ // this process happens recursively, this computed might be the last observabe of another, etc..
2025
+ observable.suspend_();
2006
2026
  }
2007
- globalState.pendingUnobservations = [];
2008
- } finally {
2009
- // Always release the guard, even if an onBUO handler (user code) threw,
2010
- // otherwise every future endBatch() would see isRunningUnobservations
2011
- // stuck true and silently stop draining pendingUnobservations forever.
2012
- globalState.isRunningUnobservations = false;
2013
2027
  }
2014
2028
  }
2029
+ globalState.pendingUnobservations = [];
2030
+ } finally {
2031
+ // Always release the guard, even if an onBUO handler (user code) threw,
2032
+ // otherwise every future endBatch() would see isRunningUnobservations
2033
+ // stuck true and silently stop draining pendingUnobservations forever.
2034
+ globalState.isRunningUnobservations = false;
2015
2035
  }
2016
2036
  }
2017
2037
  /**
@@ -3290,8 +3310,13 @@ function hasInterceptors(interceptable) {
3290
3310
  return interceptable.interceptors_ !== undefined && interceptable.interceptors_.length > 0;
3291
3311
  }
3292
3312
  function registerInterceptor(interceptable, handler) {
3293
- const interceptors = interceptable.interceptors_ || (interceptable.interceptors_ = []);
3294
- interceptors.push(handler);
3313
+ let interceptors = interceptable.interceptors_;
3314
+ if (interceptors) {
3315
+ interceptors.push(handler);
3316
+ } else {
3317
+ // Allocate at the exact size: pushing onto an empty array over-allocates its backing store
3318
+ interceptors = interceptable.interceptors_ = [handler];
3319
+ }
3295
3320
  return once(() => {
3296
3321
  const idx = interceptors.indexOf(handler);
3297
3322
  if (idx !== -1) {
@@ -3323,8 +3348,13 @@ function hasListeners(listenable) {
3323
3348
  return listenable.changeListeners_ !== undefined && listenable.changeListeners_.length > 0;
3324
3349
  }
3325
3350
  function registerListener(listenable, handler) {
3326
- const listeners = listenable.changeListeners_ || (listenable.changeListeners_ = []);
3327
- listeners.push(handler);
3351
+ let listeners = listenable.changeListeners_;
3352
+ if (listeners) {
3353
+ listeners.push(handler);
3354
+ } else {
3355
+ // Allocate at the exact size: pushing onto an empty array over-allocates its backing store
3356
+ listeners = listenable.changeListeners_ = [handler];
3357
+ }
3328
3358
  return once(() => {
3329
3359
  const idx = listeners.indexOf(handler);
3330
3360
  if (idx !== -1) {