static-injector 6.1.2 → 6.2.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 +1 -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 +259 -185
  26. package/index.js.map +4 -4
  27. package/index.mjs +259 -184
  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
@@ -56,7 +56,6 @@ __export(import_exports, {
56
56
  assertNotDestroyed: () => assertNotDestroyed,
57
57
  assertNotInReactiveContext: () => assertNotInReactiveContext,
58
58
  attachInjectFlag: () => attachInjectFlag,
59
- catchInjectorError: () => catchInjectorError,
60
59
  computed: () => computed,
61
60
  convertToBitFlags: () => convertToBitFlags,
62
61
  createInjector: () => createInjector2,
@@ -69,7 +68,7 @@ __export(import_exports, {
69
68
  getInjectableDef: () => getInjectableDef,
70
69
  getInjectorDef: () => getInjectorDef,
71
70
  getNullInjector: () => getNullInjector,
72
- inject: () => inject,
71
+ inject: () => inject2,
73
72
  injectArgs: () => injectArgs,
74
73
  injectInjectorOnly: () => injectInjectorOnly,
75
74
  isInjectable: () => isInjectable,
@@ -119,15 +118,6 @@ function getFactoryDef(type, throwNotFound) {
119
118
  return () => new type();
120
119
  }
121
120
 
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
121
  // src/import/util/property.ts
132
122
  function getClosureSafeProperty(objWithPropertyToExtract) {
133
123
  for (const key in objWithPropertyToExtract) {
@@ -138,6 +128,31 @@ function getClosureSafeProperty(objWithPropertyToExtract) {
138
128
  throw Error("");
139
129
  }
140
130
 
131
+ // src/import/render3/errors_di.ts
132
+ var NG_RUNTIME_ERROR_CODE = getClosureSafeProperty({ ngErrorCode: getClosureSafeProperty });
133
+ var NG_RUNTIME_ERROR_MESSAGE = getClosureSafeProperty({ ngErrorMessage: getClosureSafeProperty });
134
+ var NG_TOKEN_PATH = getClosureSafeProperty({ ngTokenPath: getClosureSafeProperty });
135
+ function cyclicDependencyError(token, path) {
136
+ const message = "";
137
+ return createRuntimeError(message, -200 /* CYCLIC_DI_DEPENDENCY */, path);
138
+ }
139
+ function throwProviderNotFoundError(token, injectorName) {
140
+ const errorMessage = void 0;
141
+ throw new RuntimeError(-201 /* PROVIDER_NOT_FOUND */, errorMessage);
142
+ }
143
+ function createRuntimeError(message, code, path) {
144
+ const error = new RuntimeError(code, message);
145
+ error[NG_RUNTIME_ERROR_CODE] = code;
146
+ error[NG_RUNTIME_ERROR_MESSAGE] = message;
147
+ if (path) {
148
+ error[NG_TOKEN_PATH] = path;
149
+ }
150
+ return error;
151
+ }
152
+ function getRuntimeErrorCode(error) {
153
+ return error[NG_RUNTIME_ERROR_CODE];
154
+ }
155
+
141
156
  // src/import/render3/fields.ts
142
157
  var NG_FACTORY_DEF = getClosureSafeProperty({ ɵfac: getClosureSafeProperty });
143
158
  var NG_ENV_ID = getClosureSafeProperty({ __NG_ENV_ID__: getClosureSafeProperty });
@@ -306,12 +321,6 @@ function setCurrentInjector(injector) {
306
321
 
307
322
  // src/primitives/di/src/not_found.ts
308
323
  var NOT_FOUND = Symbol("NotFound");
309
- var NotFoundError = class extends Error {
310
- name = "ɵNotFound";
311
- constructor(message) {
312
- super(message);
313
- }
314
- };
315
324
  function isNotFound(e) {
316
325
  return e === NOT_FOUND || e?.name === "ɵNotFound";
317
326
  }
@@ -342,7 +351,6 @@ var RetrievingInjector = class {
342
351
  }
343
352
  };
344
353
  var NG_TEMP_TOKEN_PATH = "ngTempTokenPath";
345
- var NG_TOKEN_PATH = "ngTokenPath";
346
354
  var NEW_LINE = /\n/gm;
347
355
  var NO_NEW_LINE = "ɵ";
348
356
  var SOURCE = "__source";
@@ -370,7 +378,7 @@ function ɵɵinject(token, flags = 0 /* Default */) {
370
378
  function ɵɵinvalidFactoryDep(index) {
371
379
  throw new RuntimeError(202 /* INVALID_FACTORY_DEPENDENCY */, void 0);
372
380
  }
373
- function inject(token, options) {
381
+ function inject2(token, options) {
374
382
  return ɵɵinject(token, convertToBitFlags(options));
375
383
  }
376
384
  function convertToBitFlags(flags) {
@@ -426,16 +434,6 @@ function attachInjectFlag(decorator, flag) {
426
434
  function getInjectFlag(token) {
427
435
  return token[DI_DECORATOR_FLAG];
428
436
  }
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
437
  function formatError(text, obj, injectorErrorName, source = null) {
440
438
  text = text && text.charAt(0) === "\n" && text.charAt(1) == NO_NEW_LINE ? text.slice(2) : text;
441
439
  let context = stringify(obj);
@@ -470,7 +468,9 @@ var INJECTOR_DEF_TYPES = new InjectionToken("");
470
468
  var NullInjector = class {
471
469
  get(token, notFoundValue = THROW_IF_NOT_FOUND) {
472
470
  if (notFoundValue === THROW_IF_NOT_FOUND) {
473
- const error = new NotFoundError(`NullInjectorError: No provider for ${stringify(token)}!`);
471
+ const message = "";
472
+ const error = createRuntimeError(message, -201 /* PROVIDER_NOT_FOUND */);
473
+ error.name = "ɵNotFound";
474
474
  throw error;
475
475
  }
476
476
  return notFoundValue;
@@ -629,23 +629,21 @@ var R3Injector = class extends EnvironmentInjector {
629
629
  this.records.set(token, record);
630
630
  }
631
631
  if (record != null) {
632
- return this.hydrate(token, record);
632
+ return this.hydrate(token, record, flags);
633
633
  }
634
634
  }
635
635
  const nextInjector = !(flags & 2 /* Self */) ? this.parent : getNullInjector();
636
636
  notFoundValue = flags & 8 /* Optional */ && notFoundValue === THROW_IF_NOT_FOUND ? null : notFoundValue;
637
637
  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;
638
+ } catch (error) {
639
+ const errorCode = getRuntimeErrorCode(error);
640
+ if (errorCode === -200 /* CYCLIC_DI_DEPENDENCY */ || errorCode === -201 /* PROVIDER_NOT_FOUND */) {
641
+ if (false) {
644
642
  } else {
645
- return catchInjectorError(e, token, "R3InjectorError", this.source);
643
+ throw new RuntimeError(errorCode, null);
646
644
  }
647
645
  } else {
648
- throw e;
646
+ throw error;
649
647
  }
650
648
  } finally {
651
649
  setInjectImplementation(previousInjectImplementation);
@@ -705,15 +703,15 @@ var R3Injector = class extends EnvironmentInjector {
705
703
  }
706
704
  this.records.set(token, record);
707
705
  }
708
- hydrate(token, record) {
706
+ hydrate(token, record, flags) {
709
707
  try {
710
708
  if (record.value === CIRCULAR) {
711
- throwCyclicDependencyError(stringify(token));
709
+ throw cyclicDependencyError(stringify(token));
712
710
  } else if (record.value === NOT_YET) {
713
711
  record.value = CIRCULAR;
714
712
  if (false) {
715
713
  } else {
716
- record.value = record.factory();
714
+ record.value = record.factory(void 0, flags);
717
715
  }
718
716
  }
719
717
  if (typeof record.value === "object" && record.value && hasOnDestroy(record.value)) {
@@ -788,7 +786,7 @@ function providerToFactory(provider, ngModuleType, providers) {
788
786
  } else if (isFactoryProvider(provider)) {
789
787
  factory = () => provider.useFactory(...injectArgs(provider.deps || []));
790
788
  } else if (isExistingProvider(provider)) {
791
- factory = () => ɵɵinject(resolveForwardRef(provider.useExisting));
789
+ factory = (_, flags) => ɵɵinject(resolveForwardRef(provider.useExisting), flags !== void 0 && flags & 8 /* Optional */ ? 8 /* Optional */ : void 0);
792
790
  } else {
793
791
  const classRef = resolveForwardRef(provider && (provider.useClass || provider.provide));
794
792
  if (false) {
@@ -933,11 +931,6 @@ function ɵɵinvalidFactory() {
933
931
  throw new Error(msg);
934
932
  }
935
933
 
936
- // src/primitives/signals/src/equality.ts
937
- function defaultEquals(a, b) {
938
- return Object.is(a, b);
939
- }
940
-
941
934
  // src/primitives/signals/src/graph.ts
942
935
  var activeConsumer = null;
943
936
  var inNotificationPhase = false;
@@ -956,12 +949,11 @@ var REACTIVE_NODE = {
956
949
  version: 0,
957
950
  lastCleanEpoch: 0,
958
951
  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,
952
+ producers: void 0,
953
+ producersTail: void 0,
954
+ consumers: void 0,
955
+ consumersTail: void 0,
956
+ recomputing: false,
965
957
  consumerAllowSignalWrites: false,
966
958
  consumerIsAlwaysLive: false,
967
959
  kind: "unknown",
@@ -981,19 +973,45 @@ function producerAccessed(node) {
981
973
  return;
982
974
  }
983
975
  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]);
976
+ const prevProducerLink = activeConsumer.producersTail;
977
+ if (prevProducerLink !== void 0 && prevProducerLink.producer === node) {
978
+ return;
979
+ }
980
+ let nextProducerLink = void 0;
981
+ const isRecomputing = activeConsumer.recomputing;
982
+ if (isRecomputing) {
983
+ nextProducerLink = prevProducerLink !== void 0 ? prevProducerLink.nextProducer : activeConsumer.producers;
984
+ if (nextProducerLink !== void 0 && nextProducerLink.producer === node) {
985
+ activeConsumer.producersTail = nextProducerLink;
986
+ nextProducerLink.lastReadVersion = node.version;
987
+ return;
990
988
  }
991
989
  }
992
- if (activeConsumer.producerNode[idx] !== node) {
993
- activeConsumer.producerNode[idx] = node;
994
- activeConsumer.producerIndexOfThis[idx] = consumerIsLive(activeConsumer) ? producerAddLiveConsumer(node, activeConsumer, idx) : 0;
990
+ const prevConsumerLink = node.consumersTail;
991
+ 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
992
+ (!isRecomputing || isValidLink(prevConsumerLink, activeConsumer))) {
993
+ return;
994
+ }
995
+ const isLive = consumerIsLive(activeConsumer);
996
+ const newLink = {
997
+ producer: node,
998
+ consumer: activeConsumer,
999
+ // instead of eagerly destroying the previous link, we delay until we've finished recomputing
1000
+ // the producers list, so that we can destroy all of the old links at once.
1001
+ nextProducer: nextProducerLink,
1002
+ prevConsumer: prevConsumerLink,
1003
+ lastReadVersion: node.version,
1004
+ nextConsumer: void 0
1005
+ };
1006
+ activeConsumer.producersTail = newLink;
1007
+ if (prevProducerLink !== void 0) {
1008
+ prevProducerLink.nextProducer = newLink;
1009
+ } else {
1010
+ activeConsumer.producers = newLink;
1011
+ }
1012
+ if (isLive) {
1013
+ producerAddLiveConsumer(node, newLink);
995
1014
  }
996
- activeConsumer.producerLastReadVersion[idx] = node.version;
997
1015
  }
998
1016
  function producerIncrementEpoch() {
999
1017
  epoch++;
@@ -1013,13 +1031,14 @@ function producerUpdateValueVersion(node) {
1013
1031
  producerMarkClean(node);
1014
1032
  }
1015
1033
  function producerNotifyConsumers(node) {
1016
- if (node.liveConsumerNode === void 0) {
1034
+ if (node.consumers === void 0) {
1017
1035
  return;
1018
1036
  }
1019
1037
  const prev = inNotificationPhase;
1020
1038
  inNotificationPhase = true;
1021
1039
  try {
1022
- for (const consumer of node.liveConsumerNode) {
1040
+ for (let link = node.consumers; link !== void 0; link = link.nextConsumer) {
1041
+ const consumer = link.consumer;
1023
1042
  if (!consumer.dirty) {
1024
1043
  consumerMarkDirty(consumer);
1025
1044
  }
@@ -1041,30 +1060,38 @@ function producerMarkClean(node) {
1041
1060
  node.lastCleanEpoch = epoch;
1042
1061
  }
1043
1062
  function consumerBeforeComputation(node) {
1044
- node && (node.nextProducerIndex = 0);
1063
+ if (node) resetConsumerBeforeComputation(node);
1045
1064
  return setActiveConsumer(node);
1046
1065
  }
1066
+ function resetConsumerBeforeComputation(node) {
1067
+ node.producersTail = void 0;
1068
+ node.recomputing = true;
1069
+ }
1047
1070
  function consumerAfterComputation(node, prevConsumer) {
1048
1071
  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]);
1072
+ if (node) finalizeConsumerAfterComputation(node);
1073
+ }
1074
+ function finalizeConsumerAfterComputation(node) {
1075
+ node.recomputing = false;
1076
+ const producersTail = node.producersTail;
1077
+ let toRemove = producersTail !== void 0 ? producersTail.nextProducer : node.producers;
1078
+ if (toRemove !== void 0) {
1079
+ if (consumerIsLive(node)) {
1080
+ do {
1081
+ toRemove = producerRemoveLiveConsumerLink(toRemove);
1082
+ } while (toRemove !== void 0);
1083
+ }
1084
+ if (producersTail !== void 0) {
1085
+ producersTail.nextProducer = void 0;
1086
+ } else {
1087
+ node.producers = void 0;
1055
1088
  }
1056
1089
  }
1057
- while (node.producerNode.length > node.nextProducerIndex) {
1058
- node.producerNode.pop();
1059
- node.producerLastReadVersion.pop();
1060
- node.producerIndexOfThis.pop();
1061
- }
1062
1090
  }
1063
1091
  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];
1092
+ for (let link = node.producers; link !== void 0; link = link.nextProducer) {
1093
+ const producer = link.producer;
1094
+ const seenVersion = link.lastReadVersion;
1068
1095
  if (seenVersion !== producer.version) {
1069
1096
  return true;
1070
1097
  }
@@ -1076,67 +1103,87 @@ function consumerPollProducersForChange(node) {
1076
1103
  return false;
1077
1104
  }
1078
1105
  function consumerDestroy(node) {
1079
- assertConsumerNode(node);
1080
1106
  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)`);
1107
+ let link = node.producers;
1108
+ while (link !== void 0) {
1109
+ link = producerRemoveLiveConsumerLink(link);
1110
+ }
1111
+ }
1112
+ node.producers = void 0;
1113
+ node.producersTail = void 0;
1114
+ node.consumers = void 0;
1115
+ node.consumersTail = void 0;
1116
+ }
1117
+ function producerAddLiveConsumer(node, link) {
1118
+ const consumersTail = node.consumersTail;
1119
+ const wasLive = consumerIsLive(node);
1120
+ if (consumersTail !== void 0) {
1121
+ link.nextConsumer = consumersTail.nextConsumer;
1122
+ consumersTail.nextConsumer = link;
1123
+ } else {
1124
+ link.nextConsumer = void 0;
1125
+ node.consumers = link;
1126
+ }
1127
+ link.prevConsumer = consumersTail;
1128
+ node.consumersTail = link;
1129
+ if (!wasLive) {
1130
+ for (let link2 = node.producers; link2 !== void 0; link2 = link2.nextProducer) {
1131
+ producerAddLiveConsumer(link2.producer, link2);
1132
+ }
1133
+ }
1134
+ }
1135
+ function producerRemoveLiveConsumerLink(link) {
1136
+ const producer = link.producer;
1137
+ const nextProducer = link.nextProducer;
1138
+ const nextConsumer = link.nextConsumer;
1139
+ const prevConsumer = link.prevConsumer;
1140
+ link.nextConsumer = void 0;
1141
+ link.prevConsumer = void 0;
1142
+ if (nextConsumer !== void 0) {
1143
+ nextConsumer.prevConsumer = prevConsumer;
1144
+ } else {
1145
+ producer.consumersTail = prevConsumer;
1104
1146
  }
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]);
1147
+ if (prevConsumer !== void 0) {
1148
+ prevConsumer.nextConsumer = nextConsumer;
1149
+ } else {
1150
+ producer.consumers = nextConsumer;
1151
+ if (!consumerIsLive(producer)) {
1152
+ let producerLink = producer.producers;
1153
+ while (producerLink !== void 0) {
1154
+ producerLink = producerRemoveLiveConsumerLink(producerLink);
1155
+ }
1108
1156
  }
1109
1157
  }
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
- }
1158
+ return nextProducer;
1121
1159
  }
1122
1160
  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;
1161
+ return node.consumerIsAlwaysLive || node.consumers !== void 0;
1136
1162
  }
1137
1163
  function runPostProducerCreatedFn(node) {
1138
1164
  postProducerCreatedFn?.(node);
1139
1165
  }
1166
+ function isValidLink(checkLink, consumer) {
1167
+ const producersTail = consumer.producersTail;
1168
+ if (producersTail !== void 0) {
1169
+ let link = consumer.producers;
1170
+ do {
1171
+ if (link === checkLink) {
1172
+ return true;
1173
+ }
1174
+ if (link === producersTail) {
1175
+ break;
1176
+ }
1177
+ link = link.nextProducer;
1178
+ } while (link !== void 0);
1179
+ }
1180
+ return false;
1181
+ }
1182
+
1183
+ // src/primitives/signals/src/equality.ts
1184
+ function defaultEquals(a, b) {
1185
+ return Object.is(a, b);
1186
+ }
1140
1187
 
1141
1188
  // src/primitives/signals/src/computed.ts
1142
1189
  function createComputed(computation, equal) {
@@ -1348,6 +1395,34 @@ function untracked(nonReactiveReadsFn) {
1348
1395
  }
1349
1396
  }
1350
1397
 
1398
+ // src/primitives/signals/src/effect.ts
1399
+ var BASE_EFFECT_NODE = /* @__PURE__ */ (() => ({
1400
+ ...REACTIVE_NODE,
1401
+ consumerIsAlwaysLive: true,
1402
+ consumerAllowSignalWrites: true,
1403
+ dirty: true,
1404
+ kind: "effect"
1405
+ }))();
1406
+ function runEffect(node) {
1407
+ node.dirty = false;
1408
+ if (node.version > 0 && !consumerPollProducersForChange(node)) {
1409
+ return;
1410
+ }
1411
+ node.version++;
1412
+ const prevNode = consumerBeforeComputation(node);
1413
+ try {
1414
+ node.cleanup();
1415
+ node.fn();
1416
+ } finally {
1417
+ consumerAfterComputation(node, prevNode);
1418
+ }
1419
+ }
1420
+
1421
+ // src/primitives/signals/index.ts
1422
+ if (false) {
1423
+ installDevToolsSignalFormatter();
1424
+ }
1425
+
1351
1426
  // src/import/render3/reactivity/api.ts
1352
1427
  function isSignal(value) {
1353
1428
  return typeof value === "function" && value[SIGNAL] !== void 0;
@@ -1391,13 +1466,13 @@ var identityFn = (v) => v;
1391
1466
  function linkedSignal(optionsOrComputation, options) {
1392
1467
  if (typeof optionsOrComputation === "function") {
1393
1468
  const getter = createLinkedSignal(optionsOrComputation, identityFn, options?.equal);
1394
- return upgradeLinkedSignalGetter(getter);
1469
+ return upgradeLinkedSignalGetter(getter, options?.debugName);
1395
1470
  } else {
1396
1471
  const getter = createLinkedSignal(optionsOrComputation.source, optionsOrComputation.computation, optionsOrComputation.equal);
1397
- return upgradeLinkedSignalGetter(getter);
1472
+ return upgradeLinkedSignalGetter(getter, optionsOrComputation.debugName);
1398
1473
  }
1399
1474
  }
1400
- function upgradeLinkedSignalGetter(getter) {
1475
+ function upgradeLinkedSignalGetter(getter, debugName) {
1401
1476
  if (false) {
1402
1477
  }
1403
1478
  const node = getter[SIGNAL];
@@ -1561,7 +1636,7 @@ function effect(effectFn, options) {
1561
1636
  if (false) {
1562
1637
  console.warn(`The 'allowSignalWrites' flag is deprecated and no longer impacts effect() (writes are always allowed)`);
1563
1638
  }
1564
- const injector = options?.injector ?? inject(Injector);
1639
+ const injector = options?.injector ?? inject2(Injector);
1565
1640
  const destroyRef = options?.manualCleanup !== true ? injector.get(DestroyRef) : null;
1566
1641
  let node;
1567
1642
  const notifier = injector.get(ChangeDetectionScheduler);
@@ -1573,35 +1648,21 @@ function effect(effectFn, options) {
1573
1648
  const effectRef = new EffectRefImpl(node);
1574
1649
  return effectRef;
1575
1650
  }
1576
- var BASE_EFFECT_NODE = /* @__PURE__ */ (() => ({
1577
- ...REACTIVE_NODE,
1578
- consumerIsAlwaysLive: true,
1579
- consumerAllowSignalWrites: true,
1580
- dirty: true,
1581
- hasRun: false,
1651
+ var EFFECT_NODE = /* @__PURE__ */ (() => ({
1652
+ ...BASE_EFFECT_NODE,
1582
1653
  cleanupFns: void 0,
1583
1654
  zone: null,
1584
- kind: "effect",
1585
1655
  onDestroyFn: noop,
1586
1656
  run() {
1587
- this.dirty = false;
1588
1657
  if (false) {
1589
1658
  throw new Error(`Schedulers cannot synchronously execute watches while scheduling.`);
1590
1659
  }
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
1660
  try {
1598
- this.maybeCleanup();
1599
- this.fn(registerCleanupFn);
1661
+ runEffect(this);
1600
1662
  } finally {
1601
- consumerAfterComputation(this, prevNode);
1602
1663
  }
1603
1664
  },
1604
- maybeCleanup() {
1665
+ cleanup() {
1605
1666
  if (!this.cleanupFns?.length) {
1606
1667
  return;
1607
1668
  }
@@ -1617,7 +1678,7 @@ var BASE_EFFECT_NODE = /* @__PURE__ */ (() => ({
1617
1678
  }
1618
1679
  }))();
1619
1680
  var ROOT_EFFECT_NODE = /* @__PURE__ */ (() => ({
1620
- ...BASE_EFFECT_NODE,
1681
+ ...EFFECT_NODE,
1621
1682
  consumerMarkedDirty() {
1622
1683
  this.scheduler.schedule(this);
1623
1684
  this.notifier.notify(12 /* RootEffect */);
@@ -1625,13 +1686,13 @@ var ROOT_EFFECT_NODE = /* @__PURE__ */ (() => ({
1625
1686
  destroy() {
1626
1687
  consumerDestroy(this);
1627
1688
  this.onDestroyFn();
1628
- this.maybeCleanup();
1689
+ this.cleanup();
1629
1690
  this.scheduler.remove(this);
1630
1691
  }
1631
1692
  }))();
1632
1693
  function createRootEffect(fn, scheduler, notifier) {
1633
1694
  const node = Object.create(ROOT_EFFECT_NODE);
1634
- node.fn = fn;
1695
+ node.fn = createEffectFn(node, fn);
1635
1696
  node.scheduler = scheduler;
1636
1697
  node.notifier = notifier;
1637
1698
  node.zone = false ? (void 0).current : null;
@@ -1639,6 +1700,11 @@ function createRootEffect(fn, scheduler, notifier) {
1639
1700
  node.notifier.notify(12 /* RootEffect */);
1640
1701
  return node;
1641
1702
  }
1703
+ function createEffectFn(node, fn) {
1704
+ return () => {
1705
+ fn((cleanupFn) => (node.cleanupFns ??= []).push(cleanupFn));
1706
+ };
1707
+ }
1642
1708
 
1643
1709
  // src/import/util/callback_scheduler.ts
1644
1710
  function scheduleCallbackWithRafRace(callback) {
@@ -1672,7 +1738,7 @@ function scheduleCallbackWithRafRace(callback) {
1672
1738
  // src/import/change_detection/scheduling/zoneless_scheduling_impl.ts
1673
1739
  var ChangeDetectionSchedulerImpl = class {
1674
1740
  runningTick = false;
1675
- #rootEffectScheduler = inject(EffectScheduler);
1741
+ #rootEffectScheduler = inject2(EffectScheduler);
1676
1742
  cancelScheduledCallback = null;
1677
1743
  notify(source) {
1678
1744
  this.cancelScheduledCallback = scheduleCallbackWithRafRace(() => {
@@ -1705,11 +1771,17 @@ var ErrorHandler = class {
1705
1771
  var INTERNAL_APPLICATION_ERROR_HANDLER = new InjectionToken("", {
1706
1772
  providedIn: "root",
1707
1773
  factory: () => {
1708
- const injector = inject(EnvironmentInjector);
1774
+ const injector = inject2(EnvironmentInjector);
1709
1775
  let userErrorHandler;
1710
1776
  return (e) => {
1711
- userErrorHandler ??= injector.get(ErrorHandler);
1712
- userErrorHandler.handleError(e);
1777
+ if (injector.destroyed && !userErrorHandler) {
1778
+ setTimeout(() => {
1779
+ throw e;
1780
+ });
1781
+ } else {
1782
+ userErrorHandler ??= injector.get(ErrorHandler);
1783
+ userErrorHandler.handleError(e);
1784
+ }
1713
1785
  };
1714
1786
  }
1715
1787
  });
@@ -1772,9 +1844,9 @@ var PendingTasksInternal = class _PendingTasksInternal {
1772
1844
  );
1773
1845
  };
1774
1846
  var PendingTasks = class _PendingTasks {
1775
- internalPendingTasks = inject(PendingTasksInternal);
1776
- scheduler = inject(ChangeDetectionScheduler);
1777
- errorHandler = inject(INTERNAL_APPLICATION_ERROR_HANDLER);
1847
+ internalPendingTasks = inject2(PendingTasksInternal);
1848
+ scheduler = inject2(ChangeDetectionScheduler);
1849
+ errorHandler = inject2(INTERNAL_APPLICATION_ERROR_HANDLER);
1778
1850
  /**
1779
1851
  * Adds a new task that should block application's stability.
1780
1852
  * @returns A cleanup function that removes a task when called.
@@ -1818,20 +1890,12 @@ var PendingTasks = class _PendingTasks {
1818
1890
  };
1819
1891
 
1820
1892
  // src/import/resource/resource.ts
1821
- var RESOURCE_VALUE_THROWS_ERRORS_DEFAULT = true;
1822
1893
  function resource(options) {
1823
1894
  if (false) {
1824
1895
  }
1825
1896
  const oldNameForParams = options.request;
1826
1897
  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
- );
1898
+ return new ResourceImpl(params, getLoader(options), options.defaultValue, options.equal ? wrapEqualityFn(options.equal) : void 0, options.injector ?? inject2(Injector));
1835
1899
  }
1836
1900
  var BaseWritableResource = class {
1837
1901
  value;
@@ -1846,18 +1910,23 @@ var BaseWritableResource = class {
1846
1910
  this.set(updateFn(untracked2(this.value)));
1847
1911
  }
1848
1912
  isLoading = computed(() => this.status() === "loading" || this.status() === "reloading");
1849
- hasValue() {
1913
+ // Use a computed here to avoid triggering reactive consumers if the value changes while staying
1914
+ // either defined or undefined.
1915
+ isValueDefined = computed(() => {
1850
1916
  if (this.isError()) {
1851
1917
  return false;
1852
1918
  }
1853
1919
  return this.value() !== void 0;
1920
+ });
1921
+ hasValue() {
1922
+ return this.isValueDefined();
1854
1923
  }
1855
1924
  asReadonly() {
1856
1925
  return this;
1857
1926
  }
1858
1927
  };
1859
1928
  var ResourceImpl = class extends BaseWritableResource {
1860
- constructor(request, loaderFn, defaultValue, equal, injector, throwErrorsFromValue = RESOURCE_VALUE_THROWS_ERRORS_DEFAULT) {
1929
+ constructor(request, loaderFn, defaultValue, equal, injector) {
1861
1930
  super(
1862
1931
  // Feed a computed signal for the value to `BaseWritableResource`, which will upgrade it to a
1863
1932
  // `WritableSignal` that delegates to `ResourceImpl.set`.
@@ -1871,11 +1940,7 @@ var ResourceImpl = class extends BaseWritableResource {
1871
1940
  return defaultValue;
1872
1941
  }
1873
1942
  if (!isResolved(streamValue)) {
1874
- if (throwErrorsFromValue) {
1875
- throw new ResourceValueError(this.error());
1876
- } else {
1877
- return defaultValue;
1878
- }
1943
+ throw new ResourceValueError(this.error());
1879
1944
  }
1880
1945
  return streamValue.value;
1881
1946
  },
@@ -1946,10 +2011,13 @@ var ResourceImpl = class extends BaseWritableResource {
1946
2011
  if (this.destroyed) {
1947
2012
  return;
1948
2013
  }
1949
- const current = untracked2(this.value);
2014
+ const error = untracked2(this.error);
1950
2015
  const state = untracked2(this.state);
1951
- if (state.status === "local" && (this.equal ? this.equal(current, value) : current === value)) {
1952
- return;
2016
+ if (!error) {
2017
+ const current = untracked2(this.value);
2018
+ if (state.status === "local" && (this.equal ? this.equal(current, value) : current === value)) {
2019
+ return;
2020
+ }
1953
2021
  }
1954
2022
  this.state.set({
1955
2023
  extRequest: state.extRequest,
@@ -2149,7 +2217,6 @@ function createRootInjector(options) {
2149
2217
  assertNotDestroyed,
2150
2218
  assertNotInReactiveContext,
2151
2219
  attachInjectFlag,
2152
- catchInjectorError,
2153
2220
  computed,
2154
2221
  convertToBitFlags,
2155
2222
  createInjector,
@@ -2189,4 +2256,11 @@ function createRootInjector(options) {
2189
2256
  * Use of this source code is governed by an MIT-style license that can be
2190
2257
  * found in the LICENSE file at https://angular.dev/license
2191
2258
  */
2259
+ /**
2260
+ * @license
2261
+ * Copyright Google LLC All Rights Reserved.
2262
+ *
2263
+ * Use of this source code is governed by an MIT-style license that can be
2264
+ * found in the LICENSE file at https://angular.io/license
2265
+ */
2192
2266
  //# sourceMappingURL=index.js.map