static-injector 6.1.2 → 6.3.0

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.
Files changed (39) hide show
  1. package/import/di/contextual.d.ts +4 -0
  2. package/import/di/forward_ref.d.ts +1 -1
  3. package/import/di/injectable.d.ts +4 -3
  4. package/import/di/injection_token.d.ts +3 -0
  5. package/import/di/injector.d.ts +2 -0
  6. package/import/di/injector_compatibility.d.ts +0 -1
  7. package/import/di/interface/provider.d.ts +11 -11
  8. package/import/di/metadata.d.ts +2 -2
  9. package/import/di/r3_injector.d.ts +8 -1
  10. package/import/error_handler.d.ts +3 -0
  11. package/import/errors.d.ts +7 -1
  12. package/import/index.d.ts +2 -0
  13. package/import/linker/destroy_ref.d.ts +12 -0
  14. package/import/pending_tasks.d.ts +3 -0
  15. package/import/render3/errors_di.d.ts +12 -2
  16. package/import/render3/reactivity/api.d.ts +2 -0
  17. package/import/render3/reactivity/asserts.d.ts +1 -1
  18. package/import/render3/reactivity/computed.d.ts +1 -0
  19. package/import/render3/reactivity/effect.d.ts +9 -8
  20. package/import/render3/reactivity/linked_signal.d.ts +3 -0
  21. package/import/render3/reactivity/signal.d.ts +1 -0
  22. package/import/render3/reactivity/untracked.d.ts +1 -0
  23. package/import/resource/api.d.ts +7 -4
  24. package/import/resource/resource.d.ts +6 -3
  25. package/index.js +268 -211
  26. package/index.js.map +4 -4
  27. package/index.mjs +267 -210
  28. package/index.mjs.map +4 -4
  29. package/package.json +2 -2
  30. package/primitives/di/index.d.ts +2 -1
  31. package/primitives/di/src/injection_token.d.ts +9 -0
  32. package/primitives/di/src/injector.d.ts +2 -1
  33. package/primitives/signals/index.d.ts +4 -2
  34. package/primitives/signals/src/effect.d.ts +26 -0
  35. package/primitives/signals/src/formatter.d.ts +18 -0
  36. package/primitives/signals/src/graph.d.ts +42 -35
  37. package/primitives/signals/src/linked_signal.d.ts +3 -2
  38. package/primitives/signals/src/watch.d.ts +0 -1
  39. package/readme.md +1 -1
package/index.js CHANGED
@@ -24,6 +24,7 @@ __export(import_exports, {
24
24
  ChangeDetectionSchedulerImpl: () => ChangeDetectionSchedulerImpl,
25
25
  DecoratorFlags: () => DecoratorFlags,
26
26
  DestroyRef: () => DestroyRef,
27
+ EffectScheduler: () => EffectScheduler,
27
28
  EnvironmentInjector: () => EnvironmentInjector,
28
29
  ErrorHandler: () => ErrorHandler,
29
30
  INJECTOR_SCOPE: () => INJECTOR_SCOPE,
@@ -56,7 +57,6 @@ __export(import_exports, {
56
57
  assertNotDestroyed: () => assertNotDestroyed,
57
58
  assertNotInReactiveContext: () => assertNotInReactiveContext,
58
59
  attachInjectFlag: () => attachInjectFlag,
59
- catchInjectorError: () => catchInjectorError,
60
60
  computed: () => computed,
61
61
  convertToBitFlags: () => convertToBitFlags,
62
62
  createInjector: () => createInjector2,
@@ -69,7 +69,7 @@ __export(import_exports, {
69
69
  getInjectableDef: () => getInjectableDef,
70
70
  getInjectorDef: () => getInjectorDef,
71
71
  getNullInjector: () => getNullInjector,
72
- inject: () => inject,
72
+ inject: () => inject2,
73
73
  injectArgs: () => injectArgs,
74
74
  injectInjectorOnly: () => injectInjectorOnly,
75
75
  isInjectable: () => isInjectable,
@@ -119,15 +119,6 @@ function getFactoryDef(type, throwNotFound) {
119
119
  return () => new type();
120
120
  }
121
121
 
122
- // src/import/render3/errors_di.ts
123
- function throwCyclicDependencyError(token, path) {
124
- throw new RuntimeError(-200 /* CYCLIC_DI_DEPENDENCY */, token);
125
- }
126
- function throwProviderNotFoundError(token, injectorName) {
127
- const errorMessage = void 0;
128
- throw new RuntimeError(-201 /* PROVIDER_NOT_FOUND */, errorMessage);
129
- }
130
-
131
122
  // src/import/util/property.ts
132
123
  function getClosureSafeProperty(objWithPropertyToExtract) {
133
124
  for (const key in objWithPropertyToExtract) {
@@ -138,6 +129,31 @@ function getClosureSafeProperty(objWithPropertyToExtract) {
138
129
  throw Error("");
139
130
  }
140
131
 
132
+ // src/import/render3/errors_di.ts
133
+ var NG_RUNTIME_ERROR_CODE = getClosureSafeProperty({ ngErrorCode: getClosureSafeProperty });
134
+ var NG_RUNTIME_ERROR_MESSAGE = getClosureSafeProperty({ ngErrorMessage: getClosureSafeProperty });
135
+ var NG_TOKEN_PATH = getClosureSafeProperty({ ngTokenPath: getClosureSafeProperty });
136
+ function cyclicDependencyError(token, path) {
137
+ const message = "";
138
+ return createRuntimeError(message, -200 /* CYCLIC_DI_DEPENDENCY */, path);
139
+ }
140
+ function throwProviderNotFoundError(token, injectorName) {
141
+ const errorMessage = void 0;
142
+ throw new RuntimeError(-201 /* PROVIDER_NOT_FOUND */, errorMessage);
143
+ }
144
+ function createRuntimeError(message, code, path) {
145
+ const error = new RuntimeError(code, message);
146
+ error[NG_RUNTIME_ERROR_CODE] = code;
147
+ error[NG_RUNTIME_ERROR_MESSAGE] = message;
148
+ if (path) {
149
+ error[NG_TOKEN_PATH] = path;
150
+ }
151
+ return error;
152
+ }
153
+ function getRuntimeErrorCode(error) {
154
+ return error[NG_RUNTIME_ERROR_CODE];
155
+ }
156
+
141
157
  // src/import/render3/fields.ts
142
158
  var NG_FACTORY_DEF = getClosureSafeProperty({ ɵfac: getClosureSafeProperty });
143
159
  var NG_ENV_ID = getClosureSafeProperty({ __NG_ENV_ID__: getClosureSafeProperty });
@@ -306,12 +322,6 @@ function setCurrentInjector(injector) {
306
322
 
307
323
  // src/primitives/di/src/not_found.ts
308
324
  var NOT_FOUND = Symbol("NotFound");
309
- var NotFoundError = class extends Error {
310
- name = "ɵNotFound";
311
- constructor(message) {
312
- super(message);
313
- }
314
- };
315
325
  function isNotFound(e) {
316
326
  return e === NOT_FOUND || e?.name === "ɵNotFound";
317
327
  }
@@ -342,7 +352,6 @@ var RetrievingInjector = class {
342
352
  }
343
353
  };
344
354
  var NG_TEMP_TOKEN_PATH = "ngTempTokenPath";
345
- var NG_TOKEN_PATH = "ngTokenPath";
346
355
  var NEW_LINE = /\n/gm;
347
356
  var NO_NEW_LINE = "ɵ";
348
357
  var SOURCE = "__source";
@@ -370,7 +379,7 @@ function ɵɵinject(token, flags = 0 /* Default */) {
370
379
  function ɵɵinvalidFactoryDep(index) {
371
380
  throw new RuntimeError(202 /* INVALID_FACTORY_DEPENDENCY */, void 0);
372
381
  }
373
- function inject(token, options) {
382
+ function inject2(token, options) {
374
383
  return ɵɵinject(token, convertToBitFlags(options));
375
384
  }
376
385
  function convertToBitFlags(flags) {
@@ -426,16 +435,6 @@ function attachInjectFlag(decorator, flag) {
426
435
  function getInjectFlag(token) {
427
436
  return token[DI_DECORATOR_FLAG];
428
437
  }
429
- function catchInjectorError(e, token, injectorErrorName, source) {
430
- const tokenPath = e[NG_TEMP_TOKEN_PATH];
431
- if (token[SOURCE]) {
432
- tokenPath.unshift(token[SOURCE]);
433
- }
434
- e.message = formatError("\n" + e.message, tokenPath, injectorErrorName, source);
435
- e[NG_TOKEN_PATH] = tokenPath;
436
- e[NG_TEMP_TOKEN_PATH] = null;
437
- throw e;
438
- }
439
438
  function formatError(text, obj, injectorErrorName, source = null) {
440
439
  text = text && text.charAt(0) === "\n" && text.charAt(1) == NO_NEW_LINE ? text.slice(2) : text;
441
440
  let context = stringify(obj);
@@ -470,7 +469,9 @@ var INJECTOR_DEF_TYPES = new InjectionToken("");
470
469
  var NullInjector = class {
471
470
  get(token, notFoundValue = THROW_IF_NOT_FOUND) {
472
471
  if (notFoundValue === THROW_IF_NOT_FOUND) {
473
- const error = new NotFoundError(`NullInjectorError: No provider for ${stringify(token)}!`);
472
+ const message = "";
473
+ const error = createRuntimeError(message, -201 /* PROVIDER_NOT_FOUND */);
474
+ error.name = "ɵNotFound";
474
475
  throw error;
475
476
  }
476
477
  return notFoundValue;
@@ -629,23 +630,21 @@ var R3Injector = class extends EnvironmentInjector {
629
630
  this.records.set(token, record);
630
631
  }
631
632
  if (record != null) {
632
- return this.hydrate(token, record);
633
+ return this.hydrate(token, record, flags);
633
634
  }
634
635
  }
635
636
  const nextInjector = !(flags & 2 /* Self */) ? this.parent : getNullInjector();
636
637
  notFoundValue = flags & 8 /* Optional */ && notFoundValue === THROW_IF_NOT_FOUND ? null : notFoundValue;
637
638
  return nextInjector.get(token, notFoundValue);
638
- } catch (e) {
639
- if (isNotFound(e)) {
640
- const path = e[NG_TEMP_TOKEN_PATH] = e[NG_TEMP_TOKEN_PATH] || [];
641
- path.unshift(stringify(token));
642
- if (previousInjector) {
643
- throw e;
639
+ } catch (error) {
640
+ const errorCode = getRuntimeErrorCode(error);
641
+ if (errorCode === -200 /* CYCLIC_DI_DEPENDENCY */ || errorCode === -201 /* PROVIDER_NOT_FOUND */) {
642
+ if (false) {
644
643
  } else {
645
- return catchInjectorError(e, token, "R3InjectorError", this.source);
644
+ throw new RuntimeError(errorCode, null);
646
645
  }
647
646
  } else {
648
- throw e;
647
+ throw error;
649
648
  }
650
649
  } finally {
651
650
  setInjectImplementation(previousInjectImplementation);
@@ -705,15 +704,15 @@ var R3Injector = class extends EnvironmentInjector {
705
704
  }
706
705
  this.records.set(token, record);
707
706
  }
708
- hydrate(token, record) {
707
+ hydrate(token, record, flags) {
709
708
  try {
710
709
  if (record.value === CIRCULAR) {
711
- throwCyclicDependencyError(stringify(token));
710
+ throw cyclicDependencyError(stringify(token));
712
711
  } else if (record.value === NOT_YET) {
713
712
  record.value = CIRCULAR;
714
713
  if (false) {
715
714
  } else {
716
- record.value = record.factory();
715
+ record.value = record.factory(void 0, flags);
717
716
  }
718
717
  }
719
718
  if (typeof record.value === "object" && record.value && hasOnDestroy(record.value)) {
@@ -788,7 +787,7 @@ function providerToFactory(provider, ngModuleType, providers) {
788
787
  } else if (isFactoryProvider(provider)) {
789
788
  factory = () => provider.useFactory(...injectArgs(provider.deps || []));
790
789
  } else if (isExistingProvider(provider)) {
791
- factory = () => ɵɵinject(resolveForwardRef(provider.useExisting));
790
+ factory = (_, flags) => ɵɵinject(resolveForwardRef(provider.useExisting), flags !== void 0 && flags & 8 /* Optional */ ? 8 /* Optional */ : void 0);
792
791
  } else {
793
792
  const classRef = resolveForwardRef(provider && (provider.useClass || provider.provide));
794
793
  if (false) {
@@ -933,11 +932,6 @@ function ɵɵinvalidFactory() {
933
932
  throw new Error(msg);
934
933
  }
935
934
 
936
- // src/primitives/signals/src/equality.ts
937
- function defaultEquals(a, b) {
938
- return Object.is(a, b);
939
- }
940
-
941
935
  // src/primitives/signals/src/graph.ts
942
936
  var activeConsumer = null;
943
937
  var inNotificationPhase = false;
@@ -956,12 +950,11 @@ var REACTIVE_NODE = {
956
950
  version: 0,
957
951
  lastCleanEpoch: 0,
958
952
  dirty: false,
959
- producerNode: void 0,
960
- producerLastReadVersion: void 0,
961
- producerIndexOfThis: void 0,
962
- nextProducerIndex: 0,
963
- liveConsumerNode: void 0,
964
- liveConsumerIndexOfThis: void 0,
953
+ producers: void 0,
954
+ producersTail: void 0,
955
+ consumers: void 0,
956
+ consumersTail: void 0,
957
+ recomputing: false,
965
958
  consumerAllowSignalWrites: false,
966
959
  consumerIsAlwaysLive: false,
967
960
  kind: "unknown",
@@ -981,19 +974,45 @@ function producerAccessed(node) {
981
974
  return;
982
975
  }
983
976
  activeConsumer.consumerOnSignalRead(node);
984
- const idx = activeConsumer.nextProducerIndex++;
985
- assertConsumerNode(activeConsumer);
986
- if (idx < activeConsumer.producerNode.length && activeConsumer.producerNode[idx] !== node) {
987
- if (consumerIsLive(activeConsumer)) {
988
- const staleProducer = activeConsumer.producerNode[idx];
989
- producerRemoveLiveConsumerAtIndex(staleProducer, activeConsumer.producerIndexOfThis[idx]);
977
+ const prevProducerLink = activeConsumer.producersTail;
978
+ if (prevProducerLink !== void 0 && prevProducerLink.producer === node) {
979
+ return;
980
+ }
981
+ let nextProducerLink = void 0;
982
+ const isRecomputing = activeConsumer.recomputing;
983
+ if (isRecomputing) {
984
+ nextProducerLink = prevProducerLink !== void 0 ? prevProducerLink.nextProducer : activeConsumer.producers;
985
+ if (nextProducerLink !== void 0 && nextProducerLink.producer === node) {
986
+ activeConsumer.producersTail = nextProducerLink;
987
+ nextProducerLink.lastReadVersion = node.version;
988
+ return;
990
989
  }
991
990
  }
992
- if (activeConsumer.producerNode[idx] !== node) {
993
- activeConsumer.producerNode[idx] = node;
994
- activeConsumer.producerIndexOfThis[idx] = consumerIsLive(activeConsumer) ? producerAddLiveConsumer(node, activeConsumer, idx) : 0;
991
+ const prevConsumerLink = node.consumersTail;
992
+ if (prevConsumerLink !== void 0 && prevConsumerLink.consumer === activeConsumer && // However, we have to make sure that the link we've discovered isn't from a node that is incrementally rebuilding its producer list
993
+ (!isRecomputing || isValidLink(prevConsumerLink, activeConsumer))) {
994
+ return;
995
+ }
996
+ const isLive = consumerIsLive(activeConsumer);
997
+ const newLink = {
998
+ producer: node,
999
+ consumer: activeConsumer,
1000
+ // instead of eagerly destroying the previous link, we delay until we've finished recomputing
1001
+ // the producers list, so that we can destroy all of the old links at once.
1002
+ nextProducer: nextProducerLink,
1003
+ prevConsumer: prevConsumerLink,
1004
+ lastReadVersion: node.version,
1005
+ nextConsumer: void 0
1006
+ };
1007
+ activeConsumer.producersTail = newLink;
1008
+ if (prevProducerLink !== void 0) {
1009
+ prevProducerLink.nextProducer = newLink;
1010
+ } else {
1011
+ activeConsumer.producers = newLink;
1012
+ }
1013
+ if (isLive) {
1014
+ producerAddLiveConsumer(node, newLink);
995
1015
  }
996
- activeConsumer.producerLastReadVersion[idx] = node.version;
997
1016
  }
998
1017
  function producerIncrementEpoch() {
999
1018
  epoch++;
@@ -1013,13 +1032,14 @@ function producerUpdateValueVersion(node) {
1013
1032
  producerMarkClean(node);
1014
1033
  }
1015
1034
  function producerNotifyConsumers(node) {
1016
- if (node.liveConsumerNode === void 0) {
1035
+ if (node.consumers === void 0) {
1017
1036
  return;
1018
1037
  }
1019
1038
  const prev = inNotificationPhase;
1020
1039
  inNotificationPhase = true;
1021
1040
  try {
1022
- for (const consumer of node.liveConsumerNode) {
1041
+ for (let link = node.consumers; link !== void 0; link = link.nextConsumer) {
1042
+ const consumer = link.consumer;
1023
1043
  if (!consumer.dirty) {
1024
1044
  consumerMarkDirty(consumer);
1025
1045
  }
@@ -1041,30 +1061,38 @@ function producerMarkClean(node) {
1041
1061
  node.lastCleanEpoch = epoch;
1042
1062
  }
1043
1063
  function consumerBeforeComputation(node) {
1044
- node && (node.nextProducerIndex = 0);
1064
+ if (node) resetConsumerBeforeComputation(node);
1045
1065
  return setActiveConsumer(node);
1046
1066
  }
1067
+ function resetConsumerBeforeComputation(node) {
1068
+ node.producersTail = void 0;
1069
+ node.recomputing = true;
1070
+ }
1047
1071
  function consumerAfterComputation(node, prevConsumer) {
1048
1072
  setActiveConsumer(prevConsumer);
1049
- if (!node || node.producerNode === void 0 || node.producerIndexOfThis === void 0 || node.producerLastReadVersion === void 0) {
1050
- return;
1051
- }
1052
- if (consumerIsLive(node)) {
1053
- for (let i = node.nextProducerIndex; i < node.producerNode.length; i++) {
1054
- producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);
1073
+ if (node) finalizeConsumerAfterComputation(node);
1074
+ }
1075
+ function finalizeConsumerAfterComputation(node) {
1076
+ node.recomputing = false;
1077
+ const producersTail = node.producersTail;
1078
+ let toRemove = producersTail !== void 0 ? producersTail.nextProducer : node.producers;
1079
+ if (toRemove !== void 0) {
1080
+ if (consumerIsLive(node)) {
1081
+ do {
1082
+ toRemove = producerRemoveLiveConsumerLink(toRemove);
1083
+ } while (toRemove !== void 0);
1084
+ }
1085
+ if (producersTail !== void 0) {
1086
+ producersTail.nextProducer = void 0;
1087
+ } else {
1088
+ node.producers = void 0;
1055
1089
  }
1056
1090
  }
1057
- while (node.producerNode.length > node.nextProducerIndex) {
1058
- node.producerNode.pop();
1059
- node.producerLastReadVersion.pop();
1060
- node.producerIndexOfThis.pop();
1061
- }
1062
1091
  }
1063
1092
  function consumerPollProducersForChange(node) {
1064
- assertConsumerNode(node);
1065
- for (let i = 0; i < node.producerNode.length; i++) {
1066
- const producer = node.producerNode[i];
1067
- const seenVersion = node.producerLastReadVersion[i];
1093
+ for (let link = node.producers; link !== void 0; link = link.nextProducer) {
1094
+ const producer = link.producer;
1095
+ const seenVersion = link.lastReadVersion;
1068
1096
  if (seenVersion !== producer.version) {
1069
1097
  return true;
1070
1098
  }
@@ -1076,67 +1104,87 @@ function consumerPollProducersForChange(node) {
1076
1104
  return false;
1077
1105
  }
1078
1106
  function consumerDestroy(node) {
1079
- assertConsumerNode(node);
1080
1107
  if (consumerIsLive(node)) {
1081
- for (let i = 0; i < node.producerNode.length; i++) {
1082
- producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);
1083
- }
1084
- }
1085
- node.producerNode.length = node.producerLastReadVersion.length = node.producerIndexOfThis.length = 0;
1086
- if (node.liveConsumerNode) {
1087
- node.liveConsumerNode.length = node.liveConsumerIndexOfThis.length = 0;
1088
- }
1089
- }
1090
- function producerAddLiveConsumer(node, consumer, indexOfThis) {
1091
- assertProducerNode(node);
1092
- if (node.liveConsumerNode.length === 0 && isConsumerNode(node)) {
1093
- for (let i = 0; i < node.producerNode.length; i++) {
1094
- node.producerIndexOfThis[i] = producerAddLiveConsumer(node.producerNode[i], node, i);
1095
- }
1096
- }
1097
- node.liveConsumerIndexOfThis.push(indexOfThis);
1098
- return node.liveConsumerNode.push(consumer) - 1;
1099
- }
1100
- function producerRemoveLiveConsumerAtIndex(node, idx) {
1101
- assertProducerNode(node);
1102
- if (false) {
1103
- throw new Error(`Assertion error: active consumer index ${idx} is out of bounds of ${node.liveConsumerNode.length} consumers)`);
1108
+ let link = node.producers;
1109
+ while (link !== void 0) {
1110
+ link = producerRemoveLiveConsumerLink(link);
1111
+ }
1112
+ }
1113
+ node.producers = void 0;
1114
+ node.producersTail = void 0;
1115
+ node.consumers = void 0;
1116
+ node.consumersTail = void 0;
1117
+ }
1118
+ function producerAddLiveConsumer(node, link) {
1119
+ const consumersTail = node.consumersTail;
1120
+ const wasLive = consumerIsLive(node);
1121
+ if (consumersTail !== void 0) {
1122
+ link.nextConsumer = consumersTail.nextConsumer;
1123
+ consumersTail.nextConsumer = link;
1124
+ } else {
1125
+ link.nextConsumer = void 0;
1126
+ node.consumers = link;
1127
+ }
1128
+ link.prevConsumer = consumersTail;
1129
+ node.consumersTail = link;
1130
+ if (!wasLive) {
1131
+ for (let link2 = node.producers; link2 !== void 0; link2 = link2.nextProducer) {
1132
+ producerAddLiveConsumer(link2.producer, link2);
1133
+ }
1134
+ }
1135
+ }
1136
+ function producerRemoveLiveConsumerLink(link) {
1137
+ const producer = link.producer;
1138
+ const nextProducer = link.nextProducer;
1139
+ const nextConsumer = link.nextConsumer;
1140
+ const prevConsumer = link.prevConsumer;
1141
+ link.nextConsumer = void 0;
1142
+ link.prevConsumer = void 0;
1143
+ if (nextConsumer !== void 0) {
1144
+ nextConsumer.prevConsumer = prevConsumer;
1145
+ } else {
1146
+ producer.consumersTail = prevConsumer;
1104
1147
  }
1105
- if (node.liveConsumerNode.length === 1 && isConsumerNode(node)) {
1106
- for (let i = 0; i < node.producerNode.length; i++) {
1107
- producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);
1148
+ if (prevConsumer !== void 0) {
1149
+ prevConsumer.nextConsumer = nextConsumer;
1150
+ } else {
1151
+ producer.consumers = nextConsumer;
1152
+ if (!consumerIsLive(producer)) {
1153
+ let producerLink = producer.producers;
1154
+ while (producerLink !== void 0) {
1155
+ producerLink = producerRemoveLiveConsumerLink(producerLink);
1156
+ }
1108
1157
  }
1109
1158
  }
1110
- const lastIdx = node.liveConsumerNode.length - 1;
1111
- node.liveConsumerNode[idx] = node.liveConsumerNode[lastIdx];
1112
- node.liveConsumerIndexOfThis[idx] = node.liveConsumerIndexOfThis[lastIdx];
1113
- node.liveConsumerNode.length--;
1114
- node.liveConsumerIndexOfThis.length--;
1115
- if (idx < node.liveConsumerNode.length) {
1116
- const idxProducer = node.liveConsumerIndexOfThis[idx];
1117
- const consumer = node.liveConsumerNode[idx];
1118
- assertConsumerNode(consumer);
1119
- consumer.producerIndexOfThis[idxProducer] = idx;
1120
- }
1159
+ return nextProducer;
1121
1160
  }
1122
1161
  function consumerIsLive(node) {
1123
- return node.consumerIsAlwaysLive || (node?.liveConsumerNode?.length ?? 0) > 0;
1124
- }
1125
- function assertConsumerNode(node) {
1126
- node.producerNode ??= [];
1127
- node.producerIndexOfThis ??= [];
1128
- node.producerLastReadVersion ??= [];
1129
- }
1130
- function assertProducerNode(node) {
1131
- node.liveConsumerNode ??= [];
1132
- node.liveConsumerIndexOfThis ??= [];
1133
- }
1134
- function isConsumerNode(node) {
1135
- return node.producerNode !== void 0;
1162
+ return node.consumerIsAlwaysLive || node.consumers !== void 0;
1136
1163
  }
1137
1164
  function runPostProducerCreatedFn(node) {
1138
1165
  postProducerCreatedFn?.(node);
1139
1166
  }
1167
+ function isValidLink(checkLink, consumer) {
1168
+ const producersTail = consumer.producersTail;
1169
+ if (producersTail !== void 0) {
1170
+ let link = consumer.producers;
1171
+ do {
1172
+ if (link === checkLink) {
1173
+ return true;
1174
+ }
1175
+ if (link === producersTail) {
1176
+ break;
1177
+ }
1178
+ link = link.nextProducer;
1179
+ } while (link !== void 0);
1180
+ }
1181
+ return false;
1182
+ }
1183
+
1184
+ // src/primitives/signals/src/equality.ts
1185
+ function defaultEquals(a, b) {
1186
+ return Object.is(a, b);
1187
+ }
1140
1188
 
1141
1189
  // src/primitives/signals/src/computed.ts
1142
1190
  function createComputed(computation, equal) {
@@ -1348,6 +1396,34 @@ function untracked(nonReactiveReadsFn) {
1348
1396
  }
1349
1397
  }
1350
1398
 
1399
+ // src/primitives/signals/src/effect.ts
1400
+ var BASE_EFFECT_NODE = /* @__PURE__ */ (() => ({
1401
+ ...REACTIVE_NODE,
1402
+ consumerIsAlwaysLive: true,
1403
+ consumerAllowSignalWrites: true,
1404
+ dirty: true,
1405
+ kind: "effect"
1406
+ }))();
1407
+ function runEffect(node) {
1408
+ node.dirty = false;
1409
+ if (node.version > 0 && !consumerPollProducersForChange(node)) {
1410
+ return;
1411
+ }
1412
+ node.version++;
1413
+ const prevNode = consumerBeforeComputation(node);
1414
+ try {
1415
+ node.cleanup();
1416
+ node.fn();
1417
+ } finally {
1418
+ consumerAfterComputation(node, prevNode);
1419
+ }
1420
+ }
1421
+
1422
+ // src/primitives/signals/index.ts
1423
+ if (false) {
1424
+ installDevToolsSignalFormatter();
1425
+ }
1426
+
1351
1427
  // src/import/render3/reactivity/api.ts
1352
1428
  function isSignal(value) {
1353
1429
  return typeof value === "function" && value[SIGNAL] !== void 0;
@@ -1391,13 +1467,13 @@ var identityFn = (v) => v;
1391
1467
  function linkedSignal(optionsOrComputation, options) {
1392
1468
  if (typeof optionsOrComputation === "function") {
1393
1469
  const getter = createLinkedSignal(optionsOrComputation, identityFn, options?.equal);
1394
- return upgradeLinkedSignalGetter(getter);
1470
+ return upgradeLinkedSignalGetter(getter, options?.debugName);
1395
1471
  } else {
1396
1472
  const getter = createLinkedSignal(optionsOrComputation.source, optionsOrComputation.computation, optionsOrComputation.equal);
1397
- return upgradeLinkedSignalGetter(getter);
1473
+ return upgradeLinkedSignalGetter(getter, optionsOrComputation.debugName);
1398
1474
  }
1399
1475
  }
1400
- function upgradeLinkedSignalGetter(getter) {
1476
+ function upgradeLinkedSignalGetter(getter, debugName) {
1401
1477
  if (false) {
1402
1478
  }
1403
1479
  const node = getter[SIGNAL];
@@ -1561,7 +1637,7 @@ function effect(effectFn, options) {
1561
1637
  if (false) {
1562
1638
  console.warn(`The 'allowSignalWrites' flag is deprecated and no longer impacts effect() (writes are always allowed)`);
1563
1639
  }
1564
- const injector = options?.injector ?? inject(Injector);
1640
+ const injector = options?.injector ?? inject2(Injector);
1565
1641
  const destroyRef = options?.manualCleanup !== true ? injector.get(DestroyRef) : null;
1566
1642
  let node;
1567
1643
  const notifier = injector.get(ChangeDetectionScheduler);
@@ -1573,35 +1649,21 @@ function effect(effectFn, options) {
1573
1649
  const effectRef = new EffectRefImpl(node);
1574
1650
  return effectRef;
1575
1651
  }
1576
- var BASE_EFFECT_NODE = /* @__PURE__ */ (() => ({
1577
- ...REACTIVE_NODE,
1578
- consumerIsAlwaysLive: true,
1579
- consumerAllowSignalWrites: true,
1580
- dirty: true,
1581
- hasRun: false,
1652
+ var EFFECT_NODE = /* @__PURE__ */ (() => ({
1653
+ ...BASE_EFFECT_NODE,
1582
1654
  cleanupFns: void 0,
1583
1655
  zone: null,
1584
- kind: "effect",
1585
1656
  onDestroyFn: noop,
1586
1657
  run() {
1587
- this.dirty = false;
1588
1658
  if (false) {
1589
1659
  throw new Error(`Schedulers cannot synchronously execute watches while scheduling.`);
1590
1660
  }
1591
- if (this.hasRun && !consumerPollProducersForChange(this)) {
1592
- return;
1593
- }
1594
- this.hasRun = true;
1595
- const registerCleanupFn = (cleanupFn) => (this.cleanupFns ??= []).push(cleanupFn);
1596
- const prevNode = consumerBeforeComputation(this);
1597
1661
  try {
1598
- this.maybeCleanup();
1599
- this.fn(registerCleanupFn);
1662
+ runEffect(this);
1600
1663
  } finally {
1601
- consumerAfterComputation(this, prevNode);
1602
1664
  }
1603
1665
  },
1604
- maybeCleanup() {
1666
+ cleanup() {
1605
1667
  if (!this.cleanupFns?.length) {
1606
1668
  return;
1607
1669
  }
@@ -1617,7 +1679,7 @@ var BASE_EFFECT_NODE = /* @__PURE__ */ (() => ({
1617
1679
  }
1618
1680
  }))();
1619
1681
  var ROOT_EFFECT_NODE = /* @__PURE__ */ (() => ({
1620
- ...BASE_EFFECT_NODE,
1682
+ ...EFFECT_NODE,
1621
1683
  consumerMarkedDirty() {
1622
1684
  this.scheduler.schedule(this);
1623
1685
  this.notifier.notify(12 /* RootEffect */);
@@ -1625,13 +1687,13 @@ var ROOT_EFFECT_NODE = /* @__PURE__ */ (() => ({
1625
1687
  destroy() {
1626
1688
  consumerDestroy(this);
1627
1689
  this.onDestroyFn();
1628
- this.maybeCleanup();
1690
+ this.cleanup();
1629
1691
  this.scheduler.remove(this);
1630
1692
  }
1631
1693
  }))();
1632
1694
  function createRootEffect(fn, scheduler, notifier) {
1633
1695
  const node = Object.create(ROOT_EFFECT_NODE);
1634
- node.fn = fn;
1696
+ node.fn = createEffectFn(node, fn);
1635
1697
  node.scheduler = scheduler;
1636
1698
  node.notifier = notifier;
1637
1699
  node.zone = false ? (void 0).current : null;
@@ -1639,44 +1701,30 @@ function createRootEffect(fn, scheduler, notifier) {
1639
1701
  node.notifier.notify(12 /* RootEffect */);
1640
1702
  return node;
1641
1703
  }
1704
+ function createEffectFn(node, fn) {
1705
+ return () => {
1706
+ fn((cleanupFn) => (node.cleanupFns ??= []).push(cleanupFn));
1707
+ };
1708
+ }
1642
1709
 
1643
1710
  // src/import/util/callback_scheduler.ts
1644
- function scheduleCallbackWithRafRace(callback) {
1645
- let timeoutId;
1646
- let animationFrameId;
1647
- function cleanup() {
1711
+ function scheduleCallbackWithMicrotask(callback) {
1712
+ queueMicrotask(() => callback());
1713
+ return () => {
1648
1714
  callback = noop;
1649
- try {
1650
- if (animationFrameId !== void 0 && typeof cancelAnimationFrame === "function") {
1651
- cancelAnimationFrame(animationFrameId);
1652
- }
1653
- if (timeoutId !== void 0) {
1654
- clearTimeout(timeoutId);
1655
- }
1656
- } catch {
1657
- }
1658
- }
1659
- timeoutId = setTimeout(() => {
1660
- callback();
1661
- cleanup();
1662
- });
1663
- if (typeof requestAnimationFrame === "function") {
1664
- animationFrameId = requestAnimationFrame(() => {
1665
- callback();
1666
- cleanup();
1667
- });
1668
- }
1669
- return () => cleanup();
1715
+ };
1670
1716
  }
1671
1717
 
1672
1718
  // src/import/change_detection/scheduling/zoneless_scheduling_impl.ts
1673
1719
  var ChangeDetectionSchedulerImpl = class {
1674
1720
  runningTick = false;
1675
- #rootEffectScheduler = inject(EffectScheduler);
1721
+ #rootEffectScheduler = inject2(EffectScheduler);
1676
1722
  cancelScheduledCallback = null;
1677
1723
  notify(source) {
1678
- this.cancelScheduledCallback = scheduleCallbackWithRafRace(() => {
1724
+ this.cancelScheduledCallback = scheduleCallbackWithMicrotask(() => {
1725
+ this.runningTick = true;
1679
1726
  this.#rootEffectScheduler.flush();
1727
+ this.cleanup();
1680
1728
  });
1681
1729
  }
1682
1730
  cleanup() {
@@ -1705,11 +1753,17 @@ var ErrorHandler = class {
1705
1753
  var INTERNAL_APPLICATION_ERROR_HANDLER = new InjectionToken("", {
1706
1754
  providedIn: "root",
1707
1755
  factory: () => {
1708
- const injector = inject(EnvironmentInjector);
1756
+ const injector = inject2(EnvironmentInjector);
1709
1757
  let userErrorHandler;
1710
1758
  return (e) => {
1711
- userErrorHandler ??= injector.get(ErrorHandler);
1712
- userErrorHandler.handleError(e);
1759
+ if (injector.destroyed && !userErrorHandler) {
1760
+ setTimeout(() => {
1761
+ throw e;
1762
+ });
1763
+ } else {
1764
+ userErrorHandler ??= injector.get(ErrorHandler);
1765
+ userErrorHandler.handleError(e);
1766
+ }
1713
1767
  };
1714
1768
  }
1715
1769
  });
@@ -1772,9 +1826,9 @@ var PendingTasksInternal = class _PendingTasksInternal {
1772
1826
  );
1773
1827
  };
1774
1828
  var PendingTasks = class _PendingTasks {
1775
- internalPendingTasks = inject(PendingTasksInternal);
1776
- scheduler = inject(ChangeDetectionScheduler);
1777
- errorHandler = inject(INTERNAL_APPLICATION_ERROR_HANDLER);
1829
+ internalPendingTasks = inject2(PendingTasksInternal);
1830
+ scheduler = inject2(ChangeDetectionScheduler);
1831
+ errorHandler = inject2(INTERNAL_APPLICATION_ERROR_HANDLER);
1778
1832
  /**
1779
1833
  * Adds a new task that should block application's stability.
1780
1834
  * @returns A cleanup function that removes a task when called.
@@ -1818,20 +1872,12 @@ var PendingTasks = class _PendingTasks {
1818
1872
  };
1819
1873
 
1820
1874
  // src/import/resource/resource.ts
1821
- var RESOURCE_VALUE_THROWS_ERRORS_DEFAULT = true;
1822
1875
  function resource(options) {
1823
1876
  if (false) {
1824
1877
  }
1825
1878
  const oldNameForParams = options.request;
1826
1879
  const params = options.params ?? oldNameForParams ?? (() => null);
1827
- return new ResourceImpl(
1828
- params,
1829
- getLoader(options),
1830
- options.defaultValue,
1831
- options.equal ? wrapEqualityFn(options.equal) : void 0,
1832
- options.injector ?? inject(Injector),
1833
- RESOURCE_VALUE_THROWS_ERRORS_DEFAULT
1834
- );
1880
+ return new ResourceImpl(params, getLoader(options), options.defaultValue, options.equal ? wrapEqualityFn(options.equal) : void 0, options.injector ?? inject2(Injector));
1835
1881
  }
1836
1882
  var BaseWritableResource = class {
1837
1883
  value;
@@ -1846,18 +1892,23 @@ var BaseWritableResource = class {
1846
1892
  this.set(updateFn(untracked2(this.value)));
1847
1893
  }
1848
1894
  isLoading = computed(() => this.status() === "loading" || this.status() === "reloading");
1849
- hasValue() {
1895
+ // Use a computed here to avoid triggering reactive consumers if the value changes while staying
1896
+ // either defined or undefined.
1897
+ isValueDefined = computed(() => {
1850
1898
  if (this.isError()) {
1851
1899
  return false;
1852
1900
  }
1853
1901
  return this.value() !== void 0;
1902
+ });
1903
+ hasValue() {
1904
+ return this.isValueDefined();
1854
1905
  }
1855
1906
  asReadonly() {
1856
1907
  return this;
1857
1908
  }
1858
1909
  };
1859
1910
  var ResourceImpl = class extends BaseWritableResource {
1860
- constructor(request, loaderFn, defaultValue, equal, injector, throwErrorsFromValue = RESOURCE_VALUE_THROWS_ERRORS_DEFAULT) {
1911
+ constructor(request, loaderFn, defaultValue, equal, injector) {
1861
1912
  super(
1862
1913
  // Feed a computed signal for the value to `BaseWritableResource`, which will upgrade it to a
1863
1914
  // `WritableSignal` that delegates to `ResourceImpl.set`.
@@ -1871,11 +1922,7 @@ var ResourceImpl = class extends BaseWritableResource {
1871
1922
  return defaultValue;
1872
1923
  }
1873
1924
  if (!isResolved(streamValue)) {
1874
- if (throwErrorsFromValue) {
1875
- throw new ResourceValueError(this.error());
1876
- } else {
1877
- return defaultValue;
1878
- }
1925
+ throw new ResourceValueError(this.error());
1879
1926
  }
1880
1927
  return streamValue.value;
1881
1928
  },
@@ -1946,10 +1993,13 @@ var ResourceImpl = class extends BaseWritableResource {
1946
1993
  if (this.destroyed) {
1947
1994
  return;
1948
1995
  }
1949
- const current = untracked2(this.value);
1996
+ const error = untracked2(this.error);
1950
1997
  const state = untracked2(this.state);
1951
- if (state.status === "local" && (this.equal ? this.equal(current, value) : current === value)) {
1952
- return;
1998
+ if (!error) {
1999
+ const current = untracked2(this.value);
2000
+ if (state.status === "local" && (this.equal ? this.equal(current, value) : current === value)) {
2001
+ return;
2002
+ }
1953
2003
  }
1954
2004
  this.state.set({
1955
2005
  extRequest: state.extRequest,
@@ -2117,6 +2167,7 @@ function createRootInjector(options) {
2117
2167
  ChangeDetectionSchedulerImpl,
2118
2168
  DecoratorFlags,
2119
2169
  DestroyRef,
2170
+ EffectScheduler,
2120
2171
  EnvironmentInjector,
2121
2172
  ErrorHandler,
2122
2173
  INJECTOR_SCOPE,
@@ -2149,7 +2200,6 @@ function createRootInjector(options) {
2149
2200
  assertNotDestroyed,
2150
2201
  assertNotInReactiveContext,
2151
2202
  attachInjectFlag,
2152
- catchInjectorError,
2153
2203
  computed,
2154
2204
  convertToBitFlags,
2155
2205
  createInjector,
@@ -2189,4 +2239,11 @@ function createRootInjector(options) {
2189
2239
  * Use of this source code is governed by an MIT-style license that can be
2190
2240
  * found in the LICENSE file at https://angular.dev/license
2191
2241
  */
2242
+ /**
2243
+ * @license
2244
+ * Copyright Google LLC All Rights Reserved.
2245
+ *
2246
+ * Use of this source code is governed by an MIT-style license that can be
2247
+ * found in the LICENSE file at https://angular.io/license
2248
+ */
2192
2249
  //# sourceMappingURL=index.js.map