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.mjs CHANGED
@@ -26,15 +26,6 @@ function getFactoryDef(type, throwNotFound) {
26
26
  return () => new type();
27
27
  }
28
28
 
29
- // src/import/render3/errors_di.ts
30
- function throwCyclicDependencyError(token, path) {
31
- throw new RuntimeError(-200 /* CYCLIC_DI_DEPENDENCY */, token);
32
- }
33
- function throwProviderNotFoundError(token, injectorName) {
34
- const errorMessage = void 0;
35
- throw new RuntimeError(-201 /* PROVIDER_NOT_FOUND */, errorMessage);
36
- }
37
-
38
29
  // src/import/util/property.ts
39
30
  function getClosureSafeProperty(objWithPropertyToExtract) {
40
31
  for (const key in objWithPropertyToExtract) {
@@ -45,6 +36,31 @@ function getClosureSafeProperty(objWithPropertyToExtract) {
45
36
  throw Error("");
46
37
  }
47
38
 
39
+ // src/import/render3/errors_di.ts
40
+ var NG_RUNTIME_ERROR_CODE = getClosureSafeProperty({ ngErrorCode: getClosureSafeProperty });
41
+ var NG_RUNTIME_ERROR_MESSAGE = getClosureSafeProperty({ ngErrorMessage: getClosureSafeProperty });
42
+ var NG_TOKEN_PATH = getClosureSafeProperty({ ngTokenPath: getClosureSafeProperty });
43
+ function cyclicDependencyError(token, path) {
44
+ const message = "";
45
+ return createRuntimeError(message, -200 /* CYCLIC_DI_DEPENDENCY */, path);
46
+ }
47
+ function throwProviderNotFoundError(token, injectorName) {
48
+ const errorMessage = void 0;
49
+ throw new RuntimeError(-201 /* PROVIDER_NOT_FOUND */, errorMessage);
50
+ }
51
+ function createRuntimeError(message, code, path) {
52
+ const error = new RuntimeError(code, message);
53
+ error[NG_RUNTIME_ERROR_CODE] = code;
54
+ error[NG_RUNTIME_ERROR_MESSAGE] = message;
55
+ if (path) {
56
+ error[NG_TOKEN_PATH] = path;
57
+ }
58
+ return error;
59
+ }
60
+ function getRuntimeErrorCode(error) {
61
+ return error[NG_RUNTIME_ERROR_CODE];
62
+ }
63
+
48
64
  // src/import/render3/fields.ts
49
65
  var NG_FACTORY_DEF = getClosureSafeProperty({ ɵfac: getClosureSafeProperty });
50
66
  var NG_ENV_ID = getClosureSafeProperty({ __NG_ENV_ID__: getClosureSafeProperty });
@@ -213,12 +229,6 @@ function setCurrentInjector(injector) {
213
229
 
214
230
  // src/primitives/di/src/not_found.ts
215
231
  var NOT_FOUND = Symbol("NotFound");
216
- var NotFoundError = class extends Error {
217
- name = "ɵNotFound";
218
- constructor(message) {
219
- super(message);
220
- }
221
- };
222
232
  function isNotFound(e) {
223
233
  return e === NOT_FOUND || e?.name === "ɵNotFound";
224
234
  }
@@ -249,7 +259,6 @@ var RetrievingInjector = class {
249
259
  }
250
260
  };
251
261
  var NG_TEMP_TOKEN_PATH = "ngTempTokenPath";
252
- var NG_TOKEN_PATH = "ngTokenPath";
253
262
  var NEW_LINE = /\n/gm;
254
263
  var NO_NEW_LINE = "ɵ";
255
264
  var SOURCE = "__source";
@@ -277,7 +286,7 @@ function ɵɵinject(token, flags = 0 /* Default */) {
277
286
  function ɵɵinvalidFactoryDep(index) {
278
287
  throw new RuntimeError(202 /* INVALID_FACTORY_DEPENDENCY */, void 0);
279
288
  }
280
- function inject(token, options) {
289
+ function inject2(token, options) {
281
290
  return ɵɵinject(token, convertToBitFlags(options));
282
291
  }
283
292
  function convertToBitFlags(flags) {
@@ -333,16 +342,6 @@ function attachInjectFlag(decorator, flag) {
333
342
  function getInjectFlag(token) {
334
343
  return token[DI_DECORATOR_FLAG];
335
344
  }
336
- function catchInjectorError(e, token, injectorErrorName, source) {
337
- const tokenPath = e[NG_TEMP_TOKEN_PATH];
338
- if (token[SOURCE]) {
339
- tokenPath.unshift(token[SOURCE]);
340
- }
341
- e.message = formatError("\n" + e.message, tokenPath, injectorErrorName, source);
342
- e[NG_TOKEN_PATH] = tokenPath;
343
- e[NG_TEMP_TOKEN_PATH] = null;
344
- throw e;
345
- }
346
345
  function formatError(text, obj, injectorErrorName, source = null) {
347
346
  text = text && text.charAt(0) === "\n" && text.charAt(1) == NO_NEW_LINE ? text.slice(2) : text;
348
347
  let context = stringify(obj);
@@ -377,7 +376,9 @@ var INJECTOR_DEF_TYPES = new InjectionToken("");
377
376
  var NullInjector = class {
378
377
  get(token, notFoundValue = THROW_IF_NOT_FOUND) {
379
378
  if (notFoundValue === THROW_IF_NOT_FOUND) {
380
- const error = new NotFoundError(`NullInjectorError: No provider for ${stringify(token)}!`);
379
+ const message = "";
380
+ const error = createRuntimeError(message, -201 /* PROVIDER_NOT_FOUND */);
381
+ error.name = "ɵNotFound";
381
382
  throw error;
382
383
  }
383
384
  return notFoundValue;
@@ -536,23 +537,21 @@ var R3Injector = class extends EnvironmentInjector {
536
537
  this.records.set(token, record);
537
538
  }
538
539
  if (record != null) {
539
- return this.hydrate(token, record);
540
+ return this.hydrate(token, record, flags);
540
541
  }
541
542
  }
542
543
  const nextInjector = !(flags & 2 /* Self */) ? this.parent : getNullInjector();
543
544
  notFoundValue = flags & 8 /* Optional */ && notFoundValue === THROW_IF_NOT_FOUND ? null : notFoundValue;
544
545
  return nextInjector.get(token, notFoundValue);
545
- } catch (e) {
546
- if (isNotFound(e)) {
547
- const path = e[NG_TEMP_TOKEN_PATH] = e[NG_TEMP_TOKEN_PATH] || [];
548
- path.unshift(stringify(token));
549
- if (previousInjector) {
550
- throw e;
546
+ } catch (error) {
547
+ const errorCode = getRuntimeErrorCode(error);
548
+ if (errorCode === -200 /* CYCLIC_DI_DEPENDENCY */ || errorCode === -201 /* PROVIDER_NOT_FOUND */) {
549
+ if (false) {
551
550
  } else {
552
- return catchInjectorError(e, token, "R3InjectorError", this.source);
551
+ throw new RuntimeError(errorCode, null);
553
552
  }
554
553
  } else {
555
- throw e;
554
+ throw error;
556
555
  }
557
556
  } finally {
558
557
  setInjectImplementation(previousInjectImplementation);
@@ -612,15 +611,15 @@ var R3Injector = class extends EnvironmentInjector {
612
611
  }
613
612
  this.records.set(token, record);
614
613
  }
615
- hydrate(token, record) {
614
+ hydrate(token, record, flags) {
616
615
  try {
617
616
  if (record.value === CIRCULAR) {
618
- throwCyclicDependencyError(stringify(token));
617
+ throw cyclicDependencyError(stringify(token));
619
618
  } else if (record.value === NOT_YET) {
620
619
  record.value = CIRCULAR;
621
620
  if (false) {
622
621
  } else {
623
- record.value = record.factory();
622
+ record.value = record.factory(void 0, flags);
624
623
  }
625
624
  }
626
625
  if (typeof record.value === "object" && record.value && hasOnDestroy(record.value)) {
@@ -695,7 +694,7 @@ function providerToFactory(provider, ngModuleType, providers) {
695
694
  } else if (isFactoryProvider(provider)) {
696
695
  factory = () => provider.useFactory(...injectArgs(provider.deps || []));
697
696
  } else if (isExistingProvider(provider)) {
698
- factory = () => ɵɵinject(resolveForwardRef(provider.useExisting));
697
+ factory = (_, flags) => ɵɵinject(resolveForwardRef(provider.useExisting), flags !== void 0 && flags & 8 /* Optional */ ? 8 /* Optional */ : void 0);
699
698
  } else {
700
699
  const classRef = resolveForwardRef(provider && (provider.useClass || provider.provide));
701
700
  if (false) {
@@ -840,11 +839,6 @@ function ɵɵinvalidFactory() {
840
839
  throw new Error(msg);
841
840
  }
842
841
 
843
- // src/primitives/signals/src/equality.ts
844
- function defaultEquals(a, b) {
845
- return Object.is(a, b);
846
- }
847
-
848
842
  // src/primitives/signals/src/graph.ts
849
843
  var activeConsumer = null;
850
844
  var inNotificationPhase = false;
@@ -863,12 +857,11 @@ var REACTIVE_NODE = {
863
857
  version: 0,
864
858
  lastCleanEpoch: 0,
865
859
  dirty: false,
866
- producerNode: void 0,
867
- producerLastReadVersion: void 0,
868
- producerIndexOfThis: void 0,
869
- nextProducerIndex: 0,
870
- liveConsumerNode: void 0,
871
- liveConsumerIndexOfThis: void 0,
860
+ producers: void 0,
861
+ producersTail: void 0,
862
+ consumers: void 0,
863
+ consumersTail: void 0,
864
+ recomputing: false,
872
865
  consumerAllowSignalWrites: false,
873
866
  consumerIsAlwaysLive: false,
874
867
  kind: "unknown",
@@ -888,19 +881,45 @@ function producerAccessed(node) {
888
881
  return;
889
882
  }
890
883
  activeConsumer.consumerOnSignalRead(node);
891
- const idx = activeConsumer.nextProducerIndex++;
892
- assertConsumerNode(activeConsumer);
893
- if (idx < activeConsumer.producerNode.length && activeConsumer.producerNode[idx] !== node) {
894
- if (consumerIsLive(activeConsumer)) {
895
- const staleProducer = activeConsumer.producerNode[idx];
896
- producerRemoveLiveConsumerAtIndex(staleProducer, activeConsumer.producerIndexOfThis[idx]);
884
+ const prevProducerLink = activeConsumer.producersTail;
885
+ if (prevProducerLink !== void 0 && prevProducerLink.producer === node) {
886
+ return;
887
+ }
888
+ let nextProducerLink = void 0;
889
+ const isRecomputing = activeConsumer.recomputing;
890
+ if (isRecomputing) {
891
+ nextProducerLink = prevProducerLink !== void 0 ? prevProducerLink.nextProducer : activeConsumer.producers;
892
+ if (nextProducerLink !== void 0 && nextProducerLink.producer === node) {
893
+ activeConsumer.producersTail = nextProducerLink;
894
+ nextProducerLink.lastReadVersion = node.version;
895
+ return;
897
896
  }
898
897
  }
899
- if (activeConsumer.producerNode[idx] !== node) {
900
- activeConsumer.producerNode[idx] = node;
901
- activeConsumer.producerIndexOfThis[idx] = consumerIsLive(activeConsumer) ? producerAddLiveConsumer(node, activeConsumer, idx) : 0;
898
+ const prevConsumerLink = node.consumersTail;
899
+ 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
900
+ (!isRecomputing || isValidLink(prevConsumerLink, activeConsumer))) {
901
+ return;
902
+ }
903
+ const isLive = consumerIsLive(activeConsumer);
904
+ const newLink = {
905
+ producer: node,
906
+ consumer: activeConsumer,
907
+ // instead of eagerly destroying the previous link, we delay until we've finished recomputing
908
+ // the producers list, so that we can destroy all of the old links at once.
909
+ nextProducer: nextProducerLink,
910
+ prevConsumer: prevConsumerLink,
911
+ lastReadVersion: node.version,
912
+ nextConsumer: void 0
913
+ };
914
+ activeConsumer.producersTail = newLink;
915
+ if (prevProducerLink !== void 0) {
916
+ prevProducerLink.nextProducer = newLink;
917
+ } else {
918
+ activeConsumer.producers = newLink;
919
+ }
920
+ if (isLive) {
921
+ producerAddLiveConsumer(node, newLink);
902
922
  }
903
- activeConsumer.producerLastReadVersion[idx] = node.version;
904
923
  }
905
924
  function producerIncrementEpoch() {
906
925
  epoch++;
@@ -920,13 +939,14 @@ function producerUpdateValueVersion(node) {
920
939
  producerMarkClean(node);
921
940
  }
922
941
  function producerNotifyConsumers(node) {
923
- if (node.liveConsumerNode === void 0) {
942
+ if (node.consumers === void 0) {
924
943
  return;
925
944
  }
926
945
  const prev = inNotificationPhase;
927
946
  inNotificationPhase = true;
928
947
  try {
929
- for (const consumer of node.liveConsumerNode) {
948
+ for (let link = node.consumers; link !== void 0; link = link.nextConsumer) {
949
+ const consumer = link.consumer;
930
950
  if (!consumer.dirty) {
931
951
  consumerMarkDirty(consumer);
932
952
  }
@@ -948,30 +968,38 @@ function producerMarkClean(node) {
948
968
  node.lastCleanEpoch = epoch;
949
969
  }
950
970
  function consumerBeforeComputation(node) {
951
- node && (node.nextProducerIndex = 0);
971
+ if (node) resetConsumerBeforeComputation(node);
952
972
  return setActiveConsumer(node);
953
973
  }
974
+ function resetConsumerBeforeComputation(node) {
975
+ node.producersTail = void 0;
976
+ node.recomputing = true;
977
+ }
954
978
  function consumerAfterComputation(node, prevConsumer) {
955
979
  setActiveConsumer(prevConsumer);
956
- if (!node || node.producerNode === void 0 || node.producerIndexOfThis === void 0 || node.producerLastReadVersion === void 0) {
957
- return;
958
- }
959
- if (consumerIsLive(node)) {
960
- for (let i = node.nextProducerIndex; i < node.producerNode.length; i++) {
961
- producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);
980
+ if (node) finalizeConsumerAfterComputation(node);
981
+ }
982
+ function finalizeConsumerAfterComputation(node) {
983
+ node.recomputing = false;
984
+ const producersTail = node.producersTail;
985
+ let toRemove = producersTail !== void 0 ? producersTail.nextProducer : node.producers;
986
+ if (toRemove !== void 0) {
987
+ if (consumerIsLive(node)) {
988
+ do {
989
+ toRemove = producerRemoveLiveConsumerLink(toRemove);
990
+ } while (toRemove !== void 0);
991
+ }
992
+ if (producersTail !== void 0) {
993
+ producersTail.nextProducer = void 0;
994
+ } else {
995
+ node.producers = void 0;
962
996
  }
963
997
  }
964
- while (node.producerNode.length > node.nextProducerIndex) {
965
- node.producerNode.pop();
966
- node.producerLastReadVersion.pop();
967
- node.producerIndexOfThis.pop();
968
- }
969
998
  }
970
999
  function consumerPollProducersForChange(node) {
971
- assertConsumerNode(node);
972
- for (let i = 0; i < node.producerNode.length; i++) {
973
- const producer = node.producerNode[i];
974
- const seenVersion = node.producerLastReadVersion[i];
1000
+ for (let link = node.producers; link !== void 0; link = link.nextProducer) {
1001
+ const producer = link.producer;
1002
+ const seenVersion = link.lastReadVersion;
975
1003
  if (seenVersion !== producer.version) {
976
1004
  return true;
977
1005
  }
@@ -983,67 +1011,87 @@ function consumerPollProducersForChange(node) {
983
1011
  return false;
984
1012
  }
985
1013
  function consumerDestroy(node) {
986
- assertConsumerNode(node);
987
1014
  if (consumerIsLive(node)) {
988
- for (let i = 0; i < node.producerNode.length; i++) {
989
- producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);
990
- }
991
- }
992
- node.producerNode.length = node.producerLastReadVersion.length = node.producerIndexOfThis.length = 0;
993
- if (node.liveConsumerNode) {
994
- node.liveConsumerNode.length = node.liveConsumerIndexOfThis.length = 0;
995
- }
996
- }
997
- function producerAddLiveConsumer(node, consumer, indexOfThis) {
998
- assertProducerNode(node);
999
- if (node.liveConsumerNode.length === 0 && isConsumerNode(node)) {
1000
- for (let i = 0; i < node.producerNode.length; i++) {
1001
- node.producerIndexOfThis[i] = producerAddLiveConsumer(node.producerNode[i], node, i);
1002
- }
1003
- }
1004
- node.liveConsumerIndexOfThis.push(indexOfThis);
1005
- return node.liveConsumerNode.push(consumer) - 1;
1006
- }
1007
- function producerRemoveLiveConsumerAtIndex(node, idx) {
1008
- assertProducerNode(node);
1009
- if (false) {
1010
- throw new Error(`Assertion error: active consumer index ${idx} is out of bounds of ${node.liveConsumerNode.length} consumers)`);
1015
+ let link = node.producers;
1016
+ while (link !== void 0) {
1017
+ link = producerRemoveLiveConsumerLink(link);
1018
+ }
1019
+ }
1020
+ node.producers = void 0;
1021
+ node.producersTail = void 0;
1022
+ node.consumers = void 0;
1023
+ node.consumersTail = void 0;
1024
+ }
1025
+ function producerAddLiveConsumer(node, link) {
1026
+ const consumersTail = node.consumersTail;
1027
+ const wasLive = consumerIsLive(node);
1028
+ if (consumersTail !== void 0) {
1029
+ link.nextConsumer = consumersTail.nextConsumer;
1030
+ consumersTail.nextConsumer = link;
1031
+ } else {
1032
+ link.nextConsumer = void 0;
1033
+ node.consumers = link;
1034
+ }
1035
+ link.prevConsumer = consumersTail;
1036
+ node.consumersTail = link;
1037
+ if (!wasLive) {
1038
+ for (let link2 = node.producers; link2 !== void 0; link2 = link2.nextProducer) {
1039
+ producerAddLiveConsumer(link2.producer, link2);
1040
+ }
1041
+ }
1042
+ }
1043
+ function producerRemoveLiveConsumerLink(link) {
1044
+ const producer = link.producer;
1045
+ const nextProducer = link.nextProducer;
1046
+ const nextConsumer = link.nextConsumer;
1047
+ const prevConsumer = link.prevConsumer;
1048
+ link.nextConsumer = void 0;
1049
+ link.prevConsumer = void 0;
1050
+ if (nextConsumer !== void 0) {
1051
+ nextConsumer.prevConsumer = prevConsumer;
1052
+ } else {
1053
+ producer.consumersTail = prevConsumer;
1011
1054
  }
1012
- if (node.liveConsumerNode.length === 1 && isConsumerNode(node)) {
1013
- for (let i = 0; i < node.producerNode.length; i++) {
1014
- producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);
1055
+ if (prevConsumer !== void 0) {
1056
+ prevConsumer.nextConsumer = nextConsumer;
1057
+ } else {
1058
+ producer.consumers = nextConsumer;
1059
+ if (!consumerIsLive(producer)) {
1060
+ let producerLink = producer.producers;
1061
+ while (producerLink !== void 0) {
1062
+ producerLink = producerRemoveLiveConsumerLink(producerLink);
1063
+ }
1015
1064
  }
1016
1065
  }
1017
- const lastIdx = node.liveConsumerNode.length - 1;
1018
- node.liveConsumerNode[idx] = node.liveConsumerNode[lastIdx];
1019
- node.liveConsumerIndexOfThis[idx] = node.liveConsumerIndexOfThis[lastIdx];
1020
- node.liveConsumerNode.length--;
1021
- node.liveConsumerIndexOfThis.length--;
1022
- if (idx < node.liveConsumerNode.length) {
1023
- const idxProducer = node.liveConsumerIndexOfThis[idx];
1024
- const consumer = node.liveConsumerNode[idx];
1025
- assertConsumerNode(consumer);
1026
- consumer.producerIndexOfThis[idxProducer] = idx;
1027
- }
1066
+ return nextProducer;
1028
1067
  }
1029
1068
  function consumerIsLive(node) {
1030
- return node.consumerIsAlwaysLive || (node?.liveConsumerNode?.length ?? 0) > 0;
1031
- }
1032
- function assertConsumerNode(node) {
1033
- node.producerNode ??= [];
1034
- node.producerIndexOfThis ??= [];
1035
- node.producerLastReadVersion ??= [];
1036
- }
1037
- function assertProducerNode(node) {
1038
- node.liveConsumerNode ??= [];
1039
- node.liveConsumerIndexOfThis ??= [];
1040
- }
1041
- function isConsumerNode(node) {
1042
- return node.producerNode !== void 0;
1069
+ return node.consumerIsAlwaysLive || node.consumers !== void 0;
1043
1070
  }
1044
1071
  function runPostProducerCreatedFn(node) {
1045
1072
  postProducerCreatedFn?.(node);
1046
1073
  }
1074
+ function isValidLink(checkLink, consumer) {
1075
+ const producersTail = consumer.producersTail;
1076
+ if (producersTail !== void 0) {
1077
+ let link = consumer.producers;
1078
+ do {
1079
+ if (link === checkLink) {
1080
+ return true;
1081
+ }
1082
+ if (link === producersTail) {
1083
+ break;
1084
+ }
1085
+ link = link.nextProducer;
1086
+ } while (link !== void 0);
1087
+ }
1088
+ return false;
1089
+ }
1090
+
1091
+ // src/primitives/signals/src/equality.ts
1092
+ function defaultEquals(a, b) {
1093
+ return Object.is(a, b);
1094
+ }
1047
1095
 
1048
1096
  // src/primitives/signals/src/computed.ts
1049
1097
  function createComputed(computation, equal) {
@@ -1255,6 +1303,34 @@ function untracked(nonReactiveReadsFn) {
1255
1303
  }
1256
1304
  }
1257
1305
 
1306
+ // src/primitives/signals/src/effect.ts
1307
+ var BASE_EFFECT_NODE = /* @__PURE__ */ (() => ({
1308
+ ...REACTIVE_NODE,
1309
+ consumerIsAlwaysLive: true,
1310
+ consumerAllowSignalWrites: true,
1311
+ dirty: true,
1312
+ kind: "effect"
1313
+ }))();
1314
+ function runEffect(node) {
1315
+ node.dirty = false;
1316
+ if (node.version > 0 && !consumerPollProducersForChange(node)) {
1317
+ return;
1318
+ }
1319
+ node.version++;
1320
+ const prevNode = consumerBeforeComputation(node);
1321
+ try {
1322
+ node.cleanup();
1323
+ node.fn();
1324
+ } finally {
1325
+ consumerAfterComputation(node, prevNode);
1326
+ }
1327
+ }
1328
+
1329
+ // src/primitives/signals/index.ts
1330
+ if (false) {
1331
+ installDevToolsSignalFormatter();
1332
+ }
1333
+
1258
1334
  // src/import/render3/reactivity/api.ts
1259
1335
  function isSignal(value) {
1260
1336
  return typeof value === "function" && value[SIGNAL] !== void 0;
@@ -1298,13 +1374,13 @@ var identityFn = (v) => v;
1298
1374
  function linkedSignal(optionsOrComputation, options) {
1299
1375
  if (typeof optionsOrComputation === "function") {
1300
1376
  const getter = createLinkedSignal(optionsOrComputation, identityFn, options?.equal);
1301
- return upgradeLinkedSignalGetter(getter);
1377
+ return upgradeLinkedSignalGetter(getter, options?.debugName);
1302
1378
  } else {
1303
1379
  const getter = createLinkedSignal(optionsOrComputation.source, optionsOrComputation.computation, optionsOrComputation.equal);
1304
- return upgradeLinkedSignalGetter(getter);
1380
+ return upgradeLinkedSignalGetter(getter, optionsOrComputation.debugName);
1305
1381
  }
1306
1382
  }
1307
- function upgradeLinkedSignalGetter(getter) {
1383
+ function upgradeLinkedSignalGetter(getter, debugName) {
1308
1384
  if (false) {
1309
1385
  }
1310
1386
  const node = getter[SIGNAL];
@@ -1468,7 +1544,7 @@ function effect(effectFn, options) {
1468
1544
  if (false) {
1469
1545
  console.warn(`The 'allowSignalWrites' flag is deprecated and no longer impacts effect() (writes are always allowed)`);
1470
1546
  }
1471
- const injector = options?.injector ?? inject(Injector);
1547
+ const injector = options?.injector ?? inject2(Injector);
1472
1548
  const destroyRef = options?.manualCleanup !== true ? injector.get(DestroyRef) : null;
1473
1549
  let node;
1474
1550
  const notifier = injector.get(ChangeDetectionScheduler);
@@ -1480,35 +1556,21 @@ function effect(effectFn, options) {
1480
1556
  const effectRef = new EffectRefImpl(node);
1481
1557
  return effectRef;
1482
1558
  }
1483
- var BASE_EFFECT_NODE = /* @__PURE__ */ (() => ({
1484
- ...REACTIVE_NODE,
1485
- consumerIsAlwaysLive: true,
1486
- consumerAllowSignalWrites: true,
1487
- dirty: true,
1488
- hasRun: false,
1559
+ var EFFECT_NODE = /* @__PURE__ */ (() => ({
1560
+ ...BASE_EFFECT_NODE,
1489
1561
  cleanupFns: void 0,
1490
1562
  zone: null,
1491
- kind: "effect",
1492
1563
  onDestroyFn: noop,
1493
1564
  run() {
1494
- this.dirty = false;
1495
1565
  if (false) {
1496
1566
  throw new Error(`Schedulers cannot synchronously execute watches while scheduling.`);
1497
1567
  }
1498
- if (this.hasRun && !consumerPollProducersForChange(this)) {
1499
- return;
1500
- }
1501
- this.hasRun = true;
1502
- const registerCleanupFn = (cleanupFn) => (this.cleanupFns ??= []).push(cleanupFn);
1503
- const prevNode = consumerBeforeComputation(this);
1504
1568
  try {
1505
- this.maybeCleanup();
1506
- this.fn(registerCleanupFn);
1569
+ runEffect(this);
1507
1570
  } finally {
1508
- consumerAfterComputation(this, prevNode);
1509
1571
  }
1510
1572
  },
1511
- maybeCleanup() {
1573
+ cleanup() {
1512
1574
  if (!this.cleanupFns?.length) {
1513
1575
  return;
1514
1576
  }
@@ -1524,7 +1586,7 @@ var BASE_EFFECT_NODE = /* @__PURE__ */ (() => ({
1524
1586
  }
1525
1587
  }))();
1526
1588
  var ROOT_EFFECT_NODE = /* @__PURE__ */ (() => ({
1527
- ...BASE_EFFECT_NODE,
1589
+ ...EFFECT_NODE,
1528
1590
  consumerMarkedDirty() {
1529
1591
  this.scheduler.schedule(this);
1530
1592
  this.notifier.notify(12 /* RootEffect */);
@@ -1532,13 +1594,13 @@ var ROOT_EFFECT_NODE = /* @__PURE__ */ (() => ({
1532
1594
  destroy() {
1533
1595
  consumerDestroy(this);
1534
1596
  this.onDestroyFn();
1535
- this.maybeCleanup();
1597
+ this.cleanup();
1536
1598
  this.scheduler.remove(this);
1537
1599
  }
1538
1600
  }))();
1539
1601
  function createRootEffect(fn, scheduler, notifier) {
1540
1602
  const node = Object.create(ROOT_EFFECT_NODE);
1541
- node.fn = fn;
1603
+ node.fn = createEffectFn(node, fn);
1542
1604
  node.scheduler = scheduler;
1543
1605
  node.notifier = notifier;
1544
1606
  node.zone = false ? (void 0).current : null;
@@ -1546,6 +1608,11 @@ function createRootEffect(fn, scheduler, notifier) {
1546
1608
  node.notifier.notify(12 /* RootEffect */);
1547
1609
  return node;
1548
1610
  }
1611
+ function createEffectFn(node, fn) {
1612
+ return () => {
1613
+ fn((cleanupFn) => (node.cleanupFns ??= []).push(cleanupFn));
1614
+ };
1615
+ }
1549
1616
 
1550
1617
  // src/import/util/callback_scheduler.ts
1551
1618
  function scheduleCallbackWithRafRace(callback) {
@@ -1579,7 +1646,7 @@ function scheduleCallbackWithRafRace(callback) {
1579
1646
  // src/import/change_detection/scheduling/zoneless_scheduling_impl.ts
1580
1647
  var ChangeDetectionSchedulerImpl = class {
1581
1648
  runningTick = false;
1582
- #rootEffectScheduler = inject(EffectScheduler);
1649
+ #rootEffectScheduler = inject2(EffectScheduler);
1583
1650
  cancelScheduledCallback = null;
1584
1651
  notify(source) {
1585
1652
  this.cancelScheduledCallback = scheduleCallbackWithRafRace(() => {
@@ -1612,11 +1679,17 @@ var ErrorHandler = class {
1612
1679
  var INTERNAL_APPLICATION_ERROR_HANDLER = new InjectionToken("", {
1613
1680
  providedIn: "root",
1614
1681
  factory: () => {
1615
- const injector = inject(EnvironmentInjector);
1682
+ const injector = inject2(EnvironmentInjector);
1616
1683
  let userErrorHandler;
1617
1684
  return (e) => {
1618
- userErrorHandler ??= injector.get(ErrorHandler);
1619
- userErrorHandler.handleError(e);
1685
+ if (injector.destroyed && !userErrorHandler) {
1686
+ setTimeout(() => {
1687
+ throw e;
1688
+ });
1689
+ } else {
1690
+ userErrorHandler ??= injector.get(ErrorHandler);
1691
+ userErrorHandler.handleError(e);
1692
+ }
1620
1693
  };
1621
1694
  }
1622
1695
  });
@@ -1679,9 +1752,9 @@ var PendingTasksInternal = class _PendingTasksInternal {
1679
1752
  );
1680
1753
  };
1681
1754
  var PendingTasks = class _PendingTasks {
1682
- internalPendingTasks = inject(PendingTasksInternal);
1683
- scheduler = inject(ChangeDetectionScheduler);
1684
- errorHandler = inject(INTERNAL_APPLICATION_ERROR_HANDLER);
1755
+ internalPendingTasks = inject2(PendingTasksInternal);
1756
+ scheduler = inject2(ChangeDetectionScheduler);
1757
+ errorHandler = inject2(INTERNAL_APPLICATION_ERROR_HANDLER);
1685
1758
  /**
1686
1759
  * Adds a new task that should block application's stability.
1687
1760
  * @returns A cleanup function that removes a task when called.
@@ -1725,20 +1798,12 @@ var PendingTasks = class _PendingTasks {
1725
1798
  };
1726
1799
 
1727
1800
  // src/import/resource/resource.ts
1728
- var RESOURCE_VALUE_THROWS_ERRORS_DEFAULT = true;
1729
1801
  function resource(options) {
1730
1802
  if (false) {
1731
1803
  }
1732
1804
  const oldNameForParams = options.request;
1733
1805
  const params = options.params ?? oldNameForParams ?? (() => null);
1734
- return new ResourceImpl(
1735
- params,
1736
- getLoader(options),
1737
- options.defaultValue,
1738
- options.equal ? wrapEqualityFn(options.equal) : void 0,
1739
- options.injector ?? inject(Injector),
1740
- RESOURCE_VALUE_THROWS_ERRORS_DEFAULT
1741
- );
1806
+ return new ResourceImpl(params, getLoader(options), options.defaultValue, options.equal ? wrapEqualityFn(options.equal) : void 0, options.injector ?? inject2(Injector));
1742
1807
  }
1743
1808
  var BaseWritableResource = class {
1744
1809
  value;
@@ -1753,18 +1818,23 @@ var BaseWritableResource = class {
1753
1818
  this.set(updateFn(untracked2(this.value)));
1754
1819
  }
1755
1820
  isLoading = computed(() => this.status() === "loading" || this.status() === "reloading");
1756
- hasValue() {
1821
+ // Use a computed here to avoid triggering reactive consumers if the value changes while staying
1822
+ // either defined or undefined.
1823
+ isValueDefined = computed(() => {
1757
1824
  if (this.isError()) {
1758
1825
  return false;
1759
1826
  }
1760
1827
  return this.value() !== void 0;
1828
+ });
1829
+ hasValue() {
1830
+ return this.isValueDefined();
1761
1831
  }
1762
1832
  asReadonly() {
1763
1833
  return this;
1764
1834
  }
1765
1835
  };
1766
1836
  var ResourceImpl = class extends BaseWritableResource {
1767
- constructor(request, loaderFn, defaultValue, equal, injector, throwErrorsFromValue = RESOURCE_VALUE_THROWS_ERRORS_DEFAULT) {
1837
+ constructor(request, loaderFn, defaultValue, equal, injector) {
1768
1838
  super(
1769
1839
  // Feed a computed signal for the value to `BaseWritableResource`, which will upgrade it to a
1770
1840
  // `WritableSignal` that delegates to `ResourceImpl.set`.
@@ -1778,11 +1848,7 @@ var ResourceImpl = class extends BaseWritableResource {
1778
1848
  return defaultValue;
1779
1849
  }
1780
1850
  if (!isResolved(streamValue)) {
1781
- if (throwErrorsFromValue) {
1782
- throw new ResourceValueError(this.error());
1783
- } else {
1784
- return defaultValue;
1785
- }
1851
+ throw new ResourceValueError(this.error());
1786
1852
  }
1787
1853
  return streamValue.value;
1788
1854
  },
@@ -1853,10 +1919,13 @@ var ResourceImpl = class extends BaseWritableResource {
1853
1919
  if (this.destroyed) {
1854
1920
  return;
1855
1921
  }
1856
- const current = untracked2(this.value);
1922
+ const error = untracked2(this.error);
1857
1923
  const state = untracked2(this.state);
1858
- if (state.status === "local" && (this.equal ? this.equal(current, value) : current === value)) {
1859
- return;
1924
+ if (!error) {
1925
+ const current = untracked2(this.value);
1926
+ if (state.status === "local" && (this.equal ? this.equal(current, value) : current === value)) {
1927
+ return;
1928
+ }
1860
1929
  }
1861
1930
  this.state.set({
1862
1931
  extRequest: state.extRequest,
@@ -2055,7 +2124,6 @@ export {
2055
2124
  assertNotDestroyed,
2056
2125
  assertNotInReactiveContext,
2057
2126
  attachInjectFlag,
2058
- catchInjectorError,
2059
2127
  computed,
2060
2128
  convertToBitFlags,
2061
2129
  createInjector2 as createInjector,
@@ -2068,7 +2136,7 @@ export {
2068
2136
  getInjectableDef,
2069
2137
  getInjectorDef,
2070
2138
  getNullInjector,
2071
- inject,
2139
+ inject2 as inject,
2072
2140
  injectArgs,
2073
2141
  injectInjectorOnly,
2074
2142
  isInjectable,
@@ -2095,4 +2163,11 @@ export {
2095
2163
  * Use of this source code is governed by an MIT-style license that can be
2096
2164
  * found in the LICENSE file at https://angular.dev/license
2097
2165
  */
2166
+ /**
2167
+ * @license
2168
+ * Copyright Google LLC All Rights Reserved.
2169
+ *
2170
+ * Use of this source code is governed by an MIT-style license that can be
2171
+ * found in the LICENSE file at https://angular.io/license
2172
+ */
2098
2173
  //# sourceMappingURL=index.mjs.map