@ethlete/core 4.21.4 → 4.22.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.
@@ -2803,12 +2803,6 @@ const controlValueSignalWithPrevious = (control, options) => {
2803
2803
  * @deprecated Use `controlValueSignal` instead with `debounceTime` set to `300` and `debounceFirst` set to `true`.
2804
2804
  */
2805
2805
  const debouncedControlValueSignal = (control, options) => controlValueSignal(control, options ?? { debounceTime: 300, debounceFirst: true });
2806
- const injectOrRunInContext = (fn, config) => {
2807
- if (config?.injector) {
2808
- return runInInjectionContext(config.injector, fn);
2809
- }
2810
- return fn();
2811
- };
2812
2806
  const transformOrReturn = (src, config) => {
2813
2807
  const transformer = config?.transform;
2814
2808
  if (transformer) {
@@ -2816,61 +2810,166 @@ const transformOrReturn = (src, config) => {
2816
2810
  }
2817
2811
  return src;
2818
2812
  };
2813
+ /** Inject the current router event */
2814
+ const injectRouterEvent = () => {
2815
+ const router = inject(Router);
2816
+ return toSignal(router.events, { initialValue: null });
2817
+ };
2818
+ /**
2819
+ * Inject the current url.
2820
+ * The url includes query params as well as the fragment. Use `injectRoute` instead if you are not intrusted in those.
2821
+ * @example "/my-page?query=1&param=true#fragment"
2822
+ */
2823
+ const injectUrl = () => {
2824
+ const event = injectRouterEvent();
2825
+ const router = inject(Router);
2826
+ const url = signal(router.url);
2827
+ effect(() => {
2828
+ const currentEvent = event();
2829
+ untracked(() => {
2830
+ if (currentEvent instanceof NavigationEnd) {
2831
+ url.set(currentEvent.urlAfterRedirects);
2832
+ }
2833
+ });
2834
+ });
2835
+ return url.asReadonly();
2836
+ };
2837
+ /**
2838
+ * Inject the current route
2839
+ * @example "/my-page"
2840
+ */
2841
+ const injectRoute = () => {
2842
+ const url = injectUrl();
2843
+ return computed(() => {
2844
+ const fullUrl = url();
2845
+ const urlWithoutQueryParams = fullUrl.split('?')[0] ?? '';
2846
+ const withoutFragment = urlWithoutQueryParams.split('#')[0] ?? '';
2847
+ return withoutFragment;
2848
+ });
2849
+ };
2850
+ const createRouterState = (router) => {
2851
+ let route = router.routerState.snapshot.root;
2852
+ while (route.firstChild) {
2853
+ route = route.firstChild;
2854
+ }
2855
+ const { data, params, queryParams, title, fragment } = route;
2856
+ return {
2857
+ data,
2858
+ pathParams: params,
2859
+ queryParams,
2860
+ title: title ?? null,
2861
+ fragment,
2862
+ };
2863
+ };
2864
+ /**
2865
+ * Inject the complete router state. This includes the current route data, path params, query params, title and fragment.
2866
+ */
2867
+ const injectRouterState = () => {
2868
+ const url = injectUrl();
2869
+ const router = inject(Router);
2870
+ const routerState = signal(createRouterState(router));
2871
+ effect(() => {
2872
+ url();
2873
+ untracked(() => routerState.set(createRouterState(router)));
2874
+ });
2875
+ return routerState.asReadonly();
2876
+ };
2819
2877
  /** Inject a signal containing the current route fragment (the part after the # inside the url if present) */
2820
2878
  const injectFragment = (config) => {
2821
- return injectOrRunInContext(() => {
2822
- const routerStateService = inject(RouterStateService);
2823
- const src = toSignal(routerStateService.fragment$, { initialValue: routerStateService.fragment });
2824
- return transformOrReturn(src, config);
2825
- }, config);
2879
+ const routerState = injectRouterState();
2880
+ const fragment = computed(() => routerState().fragment);
2881
+ return transformOrReturn(fragment, config);
2826
2882
  };
2827
2883
  /** Inject all currently available query parameters as a signal */
2828
- const injectQueryParams = (config) => {
2829
- return injectOrRunInContext(() => {
2830
- const routerStateService = inject(RouterStateService);
2831
- return toSignal(routerStateService.queryParams$, { initialValue: routerStateService.queryParams });
2832
- }, config);
2884
+ const injectQueryParams = () => {
2885
+ const routerState = injectRouterState();
2886
+ const queryParams = computed(() => routerState().queryParams);
2887
+ return queryParams;
2833
2888
  };
2834
2889
  /** Inject all currently available route data as a signal */
2835
- const injectRouteData = (config) => {
2836
- return injectOrRunInContext(() => {
2837
- const routerStateService = inject(RouterStateService);
2838
- return toSignal(routerStateService.data$, { initialValue: routerStateService.data });
2839
- }, config);
2890
+ const injectRouteData = () => {
2891
+ const routerState = injectRouterState();
2892
+ const data = computed(() => routerState().data);
2893
+ return data;
2840
2894
  };
2841
2895
  /** Inject the current route title as a signal */
2842
2896
  const injectRouteTitle = (config) => {
2843
- return injectOrRunInContext(() => {
2844
- const routerStateService = inject(RouterStateService);
2845
- const src = toSignal(routerStateService.title$, { initialValue: routerStateService.title });
2846
- return transformOrReturn(src, config);
2847
- }, config);
2897
+ const routerState = injectRouterState();
2898
+ const title = computed(() => routerState().title);
2899
+ return transformOrReturn(title, config);
2848
2900
  };
2849
2901
  /** Inject all currently available path parameters as a signal */
2850
- const injectPathParams = (config) => {
2851
- return injectOrRunInContext(() => {
2852
- const routerStateService = inject(RouterStateService);
2853
- return toSignal(routerStateService.pathParams$, { initialValue: routerStateService.pathParams });
2854
- }, config);
2902
+ const injectPathParams = () => {
2903
+ const routerState = injectRouterState();
2904
+ const pathParams = computed(() => routerState().pathParams);
2905
+ return pathParams;
2855
2906
  };
2856
2907
  /** Inject a specific query parameter as a signal */
2857
2908
  const injectQueryParam = (key, config) => {
2858
- const queryParams = injectQueryParams(config);
2909
+ const queryParams = injectQueryParams();
2859
2910
  const src = computed(() => queryParams()[key] ?? null);
2860
2911
  return transformOrReturn(src, config);
2861
2912
  };
2862
2913
  /** Inject a specific route data item as a signal */
2863
2914
  const injectRouteDataItem = (key, config) => {
2864
- const data = injectRouteData(config);
2915
+ const data = injectRouteData();
2865
2916
  const src = computed(() => data()[key] ?? null);
2866
2917
  return transformOrReturn(src, config);
2867
2918
  };
2868
2919
  /** Inject a specific path parameter as a signal */
2869
2920
  const injectPathParam = (key, config) => {
2870
- const pathParams = injectPathParams(config);
2921
+ const pathParams = injectPathParams();
2871
2922
  const src = computed(() => pathParams()[key] ?? null);
2872
2923
  return transformOrReturn(src, config);
2873
2924
  };
2925
+ /**
2926
+ * Inject query params that changed during navigation. Unchanged query params will be ignored.
2927
+ * Removed query params will be represented by the symbol `ET_PROPERTY_REMOVED`.
2928
+ */
2929
+ const injectQueryParamChanges = () => {
2930
+ const queryParams = injectQueryParams();
2931
+ const prevQueryParams = previousSignalValue(queryParams);
2932
+ return computed(() => {
2933
+ const current = queryParams();
2934
+ const previous = prevQueryParams() ?? {};
2935
+ const changes = {};
2936
+ const allKeys = new Set([
2937
+ ...Object.keys(previous),
2938
+ ...Object.keys(current),
2939
+ ]);
2940
+ for (const key of allKeys) {
2941
+ if (!equal(previous[key], current[key])) {
2942
+ const val = current[key] === undefined ? ET_PROPERTY_REMOVED : current[key];
2943
+ changes[key] = val;
2944
+ }
2945
+ }
2946
+ return changes;
2947
+ });
2948
+ };
2949
+ /**
2950
+ * Inject path params that changed during navigation. Unchanged path params will be ignored.
2951
+ * Removed path params will be represented by the symbol `ET_PROPERTY_REMOVED`.
2952
+ */
2953
+ const injectPathParamChanges = () => {
2954
+ const pathParams = injectPathParams();
2955
+ const prevPathParams = previousSignalValue(pathParams);
2956
+ return computed(() => {
2957
+ const current = pathParams();
2958
+ const previous = prevPathParams() ?? {};
2959
+ const changes = {};
2960
+ const allKeys = new Set([
2961
+ ...Object.keys(previous),
2962
+ ...Object.keys(current),
2963
+ ]);
2964
+ for (const key of allKeys) {
2965
+ if (!equal(previous[key], current[key])) {
2966
+ const val = current[key] === undefined ? ET_PROPERTY_REMOVED : current[key];
2967
+ changes[key] = val;
2968
+ }
2969
+ }
2970
+ return changes;
2971
+ });
2972
+ };
2874
2973
  const createIsRenderedSignal = () => {
2875
2974
  const value = signal(false);
2876
2975
  nextFrame(() => {
@@ -5804,5 +5903,5 @@ const Validators = {
5804
5903
  * Generated bundle index. Do not edit.
5805
5904
  */
5806
5905
 
5807
- export { ANIMATABLE_TOKEN, ANIMATED_IF_TOKEN, ANIMATED_LIFECYCLE_TOKEN, AT_LEAST_ONE_REQUIRED, ActiveSelectionModel, AnimatableDirective, AnimatedIfDirective, AnimatedLifecycleDirective, AnimatedOverlayDirective, CURSOR_DRAG_SCROLLING_CLASS, CURSOR_DRAG_SCROLLING_PREPARED_CLASS, ClickObserverFactory, ClickObserverService, ClickOutsideDirective, ContentObserverService, CursorDragScrollDirective, DEBUG_TOKEN, DEFAULT_VIEWPORT_CONFIG, DELAYABLE_TOKEN, DebugDirective, DelayableDirective, ET_PROPERTY_REMOVED, FocusVisibleService, IS_ACTIVE_ELEMENT, IS_ARRAY_NOT_EMPTY, IS_ELEMENT, IS_EMAIL, InferMimeTypePipe, IntersectionObserverFactory, IntersectionObserverService, IsActiveElementDirective, IsArrayNotEmpty, IsElementDirective, IsEmail, KeyPressManager, LetContext, LetDirective, MUST_MATCH, Memo, MustMatch, MutationObserverFactory, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, OBSERVE_SCROLL_STATE, OBSERVE_VISIBILITY_TOKEN, ObserveContentDirective, ObserveResizeDirective, ObserveScrollStateDirective, ObserveVisibilityDirective, PropsDirective, ROOT_BOUNDARY_TOKEN, RUNTIME_ERROR_NO_DATA, RepeatDirective, ResizeObserverFactory, ResizeObserverService, RootBoundaryDirective, RouterStateService, RuntimeError, SCROLL_OBSERVER_FIRST_ELEMENT_CLASS, SCROLL_OBSERVER_IGNORE_TARGET_CLASS, SCROLL_OBSERVER_LAST_ELEMENT_CLASS, SCROLL_OBSERVER_OBSERVING_FIRST_ELEMENT_CLASS, SCROLL_OBSERVER_OBSERVING_LAST_ELEMENT_CLASS, SEO_DIRECTIVE_TOKEN, ScrollObserverFirstElementDirective, ScrollObserverIgnoreTargetDirective, ScrollObserverLastElementDirective, SelectionModel, SeoDirective, SmartBlockScrollStrategy, StructuredDataComponent, ToArrayPipe, TypedQueryList, VIEWPORT_CONFIG, ValidateAtLeastOneRequired, Validators, ViewportService, areScrollStatesEqual, bindProps, boundingClientRectToElementRect, buildSignalEffects, clamp, clone, cloneFormGroup, computedTillFalsy, computedTillTruthy, controlValueSignal, controlValueSignalWithPrevious, createCanAnimateSignal, createComponentId, createDependencyStash, createDestroy, createElementDictionary, createElementDimensions, createFlipAnimation, createFlipAnimationGroup, createHostProps, createIsRenderedSignal, createMediaQueryObservable, createMutationObservable, createPropHandlers, createProps, createReactiveBindings, createResizeObservable, createSetup, debouncedControlValueSignal, deferredSignal, deleteCookie, elementCanScroll, equal, forceReflow, formatRuntimeError, fromNextFrame, getCookie, getDomain, getElementScrollCoordinates, getFormGroupValue, getGroupMatchPoints, getGroupMatchScore, getIntersectionInfo, getKnockoutMatchScore, getMatchScoreSubLine, getObjectProperty, hasCookie, inferMimeType, injectBreakpointIsMatched, injectCurrentBreakpoint, injectFragment, injectHostElement, injectIs2Xl, injectIsLg, injectIsMd, injectIsSm, injectIsXl, injectIsXs, injectObserveBreakpoint, injectOrRunInContext, injectPathParam, injectPathParams, injectQueryParam, injectQueryParams, injectRouteData, injectRouteDataItem, injectRouteTitle, injectTemplateRef, isArray, isElementVisible, isEmptyArray, isGroupMatch, isKnockoutMatch, isObject, isObjectArray, isPrimitiveArray, maybeSignalValue, mergeSeoConfig, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, previousSignalValue, provideViewportConfig, round, routerDisableScrollTop, scrollToElement, setCookie, signalAttributes, signalClasses, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, signalVisibilityChangeClasses, switchQueryListChanges, syncSignal, templateComputed, toArray, toArrayTrackByFn, transformOrReturn, unbindProps, useCursorDragScroll };
5906
+ export { ANIMATABLE_TOKEN, ANIMATED_IF_TOKEN, ANIMATED_LIFECYCLE_TOKEN, AT_LEAST_ONE_REQUIRED, ActiveSelectionModel, AnimatableDirective, AnimatedIfDirective, AnimatedLifecycleDirective, AnimatedOverlayDirective, CURSOR_DRAG_SCROLLING_CLASS, CURSOR_DRAG_SCROLLING_PREPARED_CLASS, ClickObserverFactory, ClickObserverService, ClickOutsideDirective, ContentObserverService, CursorDragScrollDirective, DEBUG_TOKEN, DEFAULT_VIEWPORT_CONFIG, DELAYABLE_TOKEN, DebugDirective, DelayableDirective, ET_PROPERTY_REMOVED, FocusVisibleService, IS_ACTIVE_ELEMENT, IS_ARRAY_NOT_EMPTY, IS_ELEMENT, IS_EMAIL, InferMimeTypePipe, IntersectionObserverFactory, IntersectionObserverService, IsActiveElementDirective, IsArrayNotEmpty, IsElementDirective, IsEmail, KeyPressManager, LetContext, LetDirective, MUST_MATCH, Memo, MustMatch, MutationObserverFactory, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, OBSERVE_SCROLL_STATE, OBSERVE_VISIBILITY_TOKEN, ObserveContentDirective, ObserveResizeDirective, ObserveScrollStateDirective, ObserveVisibilityDirective, PropsDirective, ROOT_BOUNDARY_TOKEN, RUNTIME_ERROR_NO_DATA, RepeatDirective, ResizeObserverFactory, ResizeObserverService, RootBoundaryDirective, RouterStateService, RuntimeError, SCROLL_OBSERVER_FIRST_ELEMENT_CLASS, SCROLL_OBSERVER_IGNORE_TARGET_CLASS, SCROLL_OBSERVER_LAST_ELEMENT_CLASS, SCROLL_OBSERVER_OBSERVING_FIRST_ELEMENT_CLASS, SCROLL_OBSERVER_OBSERVING_LAST_ELEMENT_CLASS, SEO_DIRECTIVE_TOKEN, ScrollObserverFirstElementDirective, ScrollObserverIgnoreTargetDirective, ScrollObserverLastElementDirective, SelectionModel, SeoDirective, SmartBlockScrollStrategy, StructuredDataComponent, ToArrayPipe, TypedQueryList, VIEWPORT_CONFIG, ValidateAtLeastOneRequired, Validators, ViewportService, areScrollStatesEqual, bindProps, boundingClientRectToElementRect, buildSignalEffects, clamp, clone, cloneFormGroup, computedTillFalsy, computedTillTruthy, controlValueSignal, controlValueSignalWithPrevious, createCanAnimateSignal, createComponentId, createDependencyStash, createDestroy, createElementDictionary, createElementDimensions, createFlipAnimation, createFlipAnimationGroup, createHostProps, createIsRenderedSignal, createMediaQueryObservable, createMutationObservable, createPropHandlers, createProps, createReactiveBindings, createResizeObservable, createSetup, debouncedControlValueSignal, deferredSignal, deleteCookie, elementCanScroll, equal, forceReflow, formatRuntimeError, fromNextFrame, getCookie, getDomain, getElementScrollCoordinates, getFormGroupValue, getGroupMatchPoints, getGroupMatchScore, getIntersectionInfo, getKnockoutMatchScore, getMatchScoreSubLine, getObjectProperty, hasCookie, inferMimeType, injectBreakpointIsMatched, injectCurrentBreakpoint, injectFragment, injectHostElement, injectIs2Xl, injectIsLg, injectIsMd, injectIsSm, injectIsXl, injectIsXs, injectObserveBreakpoint, injectPathParam, injectPathParamChanges, injectPathParams, injectQueryParam, injectQueryParamChanges, injectQueryParams, injectRoute, injectRouteData, injectRouteDataItem, injectRouteTitle, injectRouterEvent, injectRouterState, injectTemplateRef, injectUrl, isArray, isElementVisible, isEmptyArray, isGroupMatch, isKnockoutMatch, isObject, isObjectArray, isPrimitiveArray, maybeSignalValue, mergeSeoConfig, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, previousSignalValue, provideViewportConfig, round, routerDisableScrollTop, scrollToElement, setCookie, signalAttributes, signalClasses, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, signalVisibilityChangeClasses, switchQueryListChanges, syncSignal, templateComputed, toArray, toArrayTrackByFn, transformOrReturn, unbindProps, useCursorDragScroll };
5808
5907
  //# sourceMappingURL=ethlete-core.mjs.map