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.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,44 +1608,30 @@ 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
- function scheduleCallbackWithRafRace(callback) {
1552
- let timeoutId;
1553
- let animationFrameId;
1554
- function cleanup() {
1618
+ function scheduleCallbackWithMicrotask(callback) {
1619
+ queueMicrotask(() => callback());
1620
+ return () => {
1555
1621
  callback = noop;
1556
- try {
1557
- if (animationFrameId !== void 0 && typeof cancelAnimationFrame === "function") {
1558
- cancelAnimationFrame(animationFrameId);
1559
- }
1560
- if (timeoutId !== void 0) {
1561
- clearTimeout(timeoutId);
1562
- }
1563
- } catch {
1564
- }
1565
- }
1566
- timeoutId = setTimeout(() => {
1567
- callback();
1568
- cleanup();
1569
- });
1570
- if (typeof requestAnimationFrame === "function") {
1571
- animationFrameId = requestAnimationFrame(() => {
1572
- callback();
1573
- cleanup();
1574
- });
1575
- }
1576
- return () => cleanup();
1622
+ };
1577
1623
  }
1578
1624
 
1579
1625
  // src/import/change_detection/scheduling/zoneless_scheduling_impl.ts
1580
1626
  var ChangeDetectionSchedulerImpl = class {
1581
1627
  runningTick = false;
1582
- #rootEffectScheduler = inject(EffectScheduler);
1628
+ #rootEffectScheduler = inject2(EffectScheduler);
1583
1629
  cancelScheduledCallback = null;
1584
1630
  notify(source) {
1585
- this.cancelScheduledCallback = scheduleCallbackWithRafRace(() => {
1631
+ this.cancelScheduledCallback = scheduleCallbackWithMicrotask(() => {
1632
+ this.runningTick = true;
1586
1633
  this.#rootEffectScheduler.flush();
1634
+ this.cleanup();
1587
1635
  });
1588
1636
  }
1589
1637
  cleanup() {
@@ -1612,11 +1660,17 @@ var ErrorHandler = class {
1612
1660
  var INTERNAL_APPLICATION_ERROR_HANDLER = new InjectionToken("", {
1613
1661
  providedIn: "root",
1614
1662
  factory: () => {
1615
- const injector = inject(EnvironmentInjector);
1663
+ const injector = inject2(EnvironmentInjector);
1616
1664
  let userErrorHandler;
1617
1665
  return (e) => {
1618
- userErrorHandler ??= injector.get(ErrorHandler);
1619
- userErrorHandler.handleError(e);
1666
+ if (injector.destroyed && !userErrorHandler) {
1667
+ setTimeout(() => {
1668
+ throw e;
1669
+ });
1670
+ } else {
1671
+ userErrorHandler ??= injector.get(ErrorHandler);
1672
+ userErrorHandler.handleError(e);
1673
+ }
1620
1674
  };
1621
1675
  }
1622
1676
  });
@@ -1679,9 +1733,9 @@ var PendingTasksInternal = class _PendingTasksInternal {
1679
1733
  );
1680
1734
  };
1681
1735
  var PendingTasks = class _PendingTasks {
1682
- internalPendingTasks = inject(PendingTasksInternal);
1683
- scheduler = inject(ChangeDetectionScheduler);
1684
- errorHandler = inject(INTERNAL_APPLICATION_ERROR_HANDLER);
1736
+ internalPendingTasks = inject2(PendingTasksInternal);
1737
+ scheduler = inject2(ChangeDetectionScheduler);
1738
+ errorHandler = inject2(INTERNAL_APPLICATION_ERROR_HANDLER);
1685
1739
  /**
1686
1740
  * Adds a new task that should block application's stability.
1687
1741
  * @returns A cleanup function that removes a task when called.
@@ -1725,20 +1779,12 @@ var PendingTasks = class _PendingTasks {
1725
1779
  };
1726
1780
 
1727
1781
  // src/import/resource/resource.ts
1728
- var RESOURCE_VALUE_THROWS_ERRORS_DEFAULT = true;
1729
1782
  function resource(options) {
1730
1783
  if (false) {
1731
1784
  }
1732
1785
  const oldNameForParams = options.request;
1733
1786
  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
- );
1787
+ return new ResourceImpl(params, getLoader(options), options.defaultValue, options.equal ? wrapEqualityFn(options.equal) : void 0, options.injector ?? inject2(Injector));
1742
1788
  }
1743
1789
  var BaseWritableResource = class {
1744
1790
  value;
@@ -1753,18 +1799,23 @@ var BaseWritableResource = class {
1753
1799
  this.set(updateFn(untracked2(this.value)));
1754
1800
  }
1755
1801
  isLoading = computed(() => this.status() === "loading" || this.status() === "reloading");
1756
- hasValue() {
1802
+ // Use a computed here to avoid triggering reactive consumers if the value changes while staying
1803
+ // either defined or undefined.
1804
+ isValueDefined = computed(() => {
1757
1805
  if (this.isError()) {
1758
1806
  return false;
1759
1807
  }
1760
1808
  return this.value() !== void 0;
1809
+ });
1810
+ hasValue() {
1811
+ return this.isValueDefined();
1761
1812
  }
1762
1813
  asReadonly() {
1763
1814
  return this;
1764
1815
  }
1765
1816
  };
1766
1817
  var ResourceImpl = class extends BaseWritableResource {
1767
- constructor(request, loaderFn, defaultValue, equal, injector, throwErrorsFromValue = RESOURCE_VALUE_THROWS_ERRORS_DEFAULT) {
1818
+ constructor(request, loaderFn, defaultValue, equal, injector) {
1768
1819
  super(
1769
1820
  // Feed a computed signal for the value to `BaseWritableResource`, which will upgrade it to a
1770
1821
  // `WritableSignal` that delegates to `ResourceImpl.set`.
@@ -1778,11 +1829,7 @@ var ResourceImpl = class extends BaseWritableResource {
1778
1829
  return defaultValue;
1779
1830
  }
1780
1831
  if (!isResolved(streamValue)) {
1781
- if (throwErrorsFromValue) {
1782
- throw new ResourceValueError(this.error());
1783
- } else {
1784
- return defaultValue;
1785
- }
1832
+ throw new ResourceValueError(this.error());
1786
1833
  }
1787
1834
  return streamValue.value;
1788
1835
  },
@@ -1853,10 +1900,13 @@ var ResourceImpl = class extends BaseWritableResource {
1853
1900
  if (this.destroyed) {
1854
1901
  return;
1855
1902
  }
1856
- const current = untracked2(this.value);
1903
+ const error = untracked2(this.error);
1857
1904
  const state = untracked2(this.state);
1858
- if (state.status === "local" && (this.equal ? this.equal(current, value) : current === value)) {
1859
- return;
1905
+ if (!error) {
1906
+ const current = untracked2(this.value);
1907
+ if (state.status === "local" && (this.equal ? this.equal(current, value) : current === value)) {
1908
+ return;
1909
+ }
1860
1910
  }
1861
1911
  this.state.set({
1862
1912
  extRequest: state.extRequest,
@@ -2023,6 +2073,7 @@ export {
2023
2073
  ChangeDetectionSchedulerImpl,
2024
2074
  DecoratorFlags,
2025
2075
  DestroyRef,
2076
+ EffectScheduler,
2026
2077
  EnvironmentInjector,
2027
2078
  ErrorHandler,
2028
2079
  INJECTOR_SCOPE,
@@ -2055,7 +2106,6 @@ export {
2055
2106
  assertNotDestroyed,
2056
2107
  assertNotInReactiveContext,
2057
2108
  attachInjectFlag,
2058
- catchInjectorError,
2059
2109
  computed,
2060
2110
  convertToBitFlags,
2061
2111
  createInjector2 as createInjector,
@@ -2068,7 +2118,7 @@ export {
2068
2118
  getInjectableDef,
2069
2119
  getInjectorDef,
2070
2120
  getNullInjector,
2071
- inject,
2121
+ inject2 as inject,
2072
2122
  injectArgs,
2073
2123
  injectInjectorOnly,
2074
2124
  isInjectable,
@@ -2095,4 +2145,11 @@ export {
2095
2145
  * Use of this source code is governed by an MIT-style license that can be
2096
2146
  * found in the LICENSE file at https://angular.dev/license
2097
2147
  */
2148
+ /**
2149
+ * @license
2150
+ * Copyright Google LLC All Rights Reserved.
2151
+ *
2152
+ * Use of this source code is governed by an MIT-style license that can be
2153
+ * found in the LICENSE file at https://angular.io/license
2154
+ */
2098
2155
  //# sourceMappingURL=index.mjs.map