@benjavicente/angular-router-experimental 1.142.11 → 1.142.13

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.
package/src/index.ts CHANGED
@@ -54,10 +54,14 @@ export {
54
54
  type InjectMatchesBaseOptions,
55
55
  type InjectMatchesResult,
56
56
  } from './injectMatches'
57
- export { injectMatchRoute, type InjectMatchRouteOptions } from './injectMatchRoute'
57
+ export {
58
+ injectMatchRoute,
59
+ type InjectMatchRouteOptions,
60
+ } from './injectMatchRoute'
58
61
 
59
62
  // Injection functions
60
63
  export { injectRouter } from './injectRouter'
64
+ export { injectIsShell } from './injectIsShell'
61
65
 
62
66
  export {
63
67
  injectRouterState,
@@ -125,7 +129,7 @@ export { injectCanGoBack } from './injectCanGoBack'
125
129
 
126
130
  export { injectErrorState } from './injectErrorState'
127
131
 
128
- export { injectStore } from './injectStore'
132
+ export { injectStore } from './store/injectStore'
129
133
 
130
134
  // Link
131
135
  export { type LinkOptions as LinkInputOptions, Link } from './Link'
@@ -1,11 +1,11 @@
1
1
  import { injectRouter } from './injectRouter'
2
- import { injectStore } from './injectStore'
2
+ import { injectStore } from './store/injectStore'
3
3
 
4
4
  export function injectCanGoBack() {
5
5
  const router = injectRouter()
6
6
 
7
7
  return injectStore(
8
8
  router.stores.location,
9
- (location) => location.state.__TSR_index !== 0,
9
+ (location) => (location.state?.__TSR_index ?? 0) !== 0,
10
10
  )
11
11
  }
@@ -0,0 +1,7 @@
1
+ import { computed } from '@angular/core'
2
+ import { injectRouter } from './injectRouter'
3
+
4
+ export function injectIsShell() {
5
+ const router = injectRouter()
6
+ return computed(() => router.isShell())
7
+ }
@@ -1,12 +1,12 @@
1
1
  import { deepEqual } from '@benjavicente/router-core'
2
2
  import { injectRouter } from './injectRouter'
3
- import { injectStore } from './injectStore'
3
+ import { injectStore } from './store/injectStore'
4
+ import type * as Angular from '@angular/core'
4
5
  import type {
5
6
  AnyRouter,
6
7
  RegisteredRouter,
7
8
  RouterState,
8
9
  } from '@benjavicente/router-core'
9
- import type * as Angular from '@angular/core'
10
10
 
11
11
  export interface InjectLocationOptions<TRouter extends AnyRouter, TSelected> {
12
12
  select?: (
@@ -29,10 +29,13 @@ export function injectLocation<
29
29
  ): Angular.Signal<InjectLocationResult<TRouter, TSelected>> {
30
30
  const router = injectRouter<TRouter>()
31
31
 
32
- return injectStore(
33
- router.stores.location,
34
- (location) =>
35
- (opts?.select ? opts.select(location as any) : location) as any,
36
- { equal: deepEqual }
37
- ) as Angular.Signal<InjectLocationResult<TRouter, TSelected>>
32
+ if (!opts?.select) {
33
+ return injectStore(router.stores.location) as Angular.Signal<
34
+ InjectLocationResult<TRouter, TSelected>
35
+ >
36
+ }
37
+
38
+ return injectStore(router.stores.location, opts.select, {
39
+ equal: deepEqual,
40
+ }) as Angular.Signal<InjectLocationResult<TRouter, TSelected>>
38
41
  }
@@ -2,7 +2,7 @@ import * as Angular from '@angular/core'
2
2
  import { deepEqual, invariant } from '@benjavicente/router-core'
3
3
  import { MATCH_CONTEXT_INJECTOR_TOKEN } from './matchInjectorToken'
4
4
  import { injectRouter } from './injectRouter'
5
- import { injectStore } from './injectStore'
5
+ import { injectStore } from './store/injectStore'
6
6
  import type {
7
7
  AnyRouter,
8
8
  MakeRouteMatch,
@@ -13,6 +13,11 @@ import type {
13
13
  ThrowOrOptional,
14
14
  } from '@benjavicente/router-core'
15
15
 
16
+ const dummyStore = {
17
+ get: () => undefined,
18
+ subscribe: () => ({ unsubscribe: () => {} }),
19
+ } as any
20
+
16
21
  export interface InjectMatchBaseOptions<
17
22
  TRouter extends AnyRouter,
18
23
  TFrom,
@@ -49,8 +54,8 @@ export type InjectMatchResult<
49
54
  TSelected,
50
55
  > = unknown extends TSelected
51
56
  ? TStrict extends true
52
- ? MakeRouteMatch<TRouter['routeTree'], TFrom, TStrict>
53
- : MakeRouteMatchUnion<TRouter>
57
+ ? MakeRouteMatch<TRouter['routeTree'], TFrom, TStrict>
58
+ : MakeRouteMatchUnion<TRouter>
54
59
  : TSelected
55
60
 
56
61
  export function injectMatch<
@@ -75,48 +80,54 @@ export function injectMatch<
75
80
  ? undefined
76
81
  : Angular.inject(MATCH_CONTEXT_INJECTOR_TOKEN)
77
82
 
83
+ const match = injectStore(
84
+ opts.from
85
+ ? router.stores.getRouteMatchStore(opts.from)
86
+ : () => {
87
+ const matchId = nearestMatch?.matchId()
88
+ return matchId
89
+ ? (router.stores.matchStores.get(matchId) ?? dummyStore)
90
+ : dummyStore
91
+ },
92
+ (d) => d,
93
+ )
78
94
  const pendingRouteIds = injectStore(
79
95
  router.stores.pendingRouteIds,
80
- (s) => s,
96
+ (ids) => ids,
81
97
  )
82
98
  const isTransitioning = injectStore(
83
99
  router.stores.isTransitioning,
84
- (s) => s,
100
+ (value) => value,
85
101
  )
86
102
 
87
- const match = () => {
88
- if (opts.from) {
89
- return router.stores.getMatchStoreByRouteId(opts.from).state
90
- }
91
-
92
- return nearestMatch?.match()
93
- }
103
+ return Angular.computed(
104
+ () => {
105
+ const selectedMatch = match()
94
106
 
95
- return Angular.computed(() => {
96
- const selectedMatch = match()
107
+ if (selectedMatch !== undefined) {
108
+ return opts.select ? opts.select(selectedMatch as any) : selectedMatch
109
+ }
97
110
 
98
- if (selectedMatch !== undefined) {
99
- return opts.select ? opts.select(selectedMatch as any) : selectedMatch
100
- }
111
+ const hasPendingMatch = opts.from
112
+ ? Boolean(pendingRouteIds()[opts.from!])
113
+ : (nearestMatch?.hasPending() ?? false)
101
114
 
102
- const hasPendingMatch = opts.from
103
- ? Boolean(pendingRouteIds()[opts.from])
104
- : nearestMatch?.hasPending() ?? false
115
+ if (
116
+ !hasPendingMatch &&
117
+ !isTransitioning() &&
118
+ (opts.shouldThrow ?? true)
119
+ ) {
120
+ if (process.env.NODE_ENV !== 'production') {
121
+ throw new Error(
122
+ `Invariant failed: Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`,
123
+ )
124
+ }
105
125
 
106
- if (
107
- !hasPendingMatch &&
108
- !isTransitioning() &&
109
- (opts.shouldThrow ?? true)
110
- ) {
111
- if (process.env.NODE_ENV !== 'production') {
112
- throw new Error(
113
- `Invariant failed: Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`,
114
- )
126
+ invariant()
115
127
  }
116
128
 
117
- invariant()
118
- }
119
-
120
- return undefined
121
- }, { equal: deepEqual }) as any
129
+ return undefined
130
+ },
131
+ { equal: deepEqual },
132
+ ) as any
122
133
  }
@@ -1,6 +1,6 @@
1
1
  import * as Angular from '@angular/core'
2
2
  import { injectRouter } from './injectRouter'
3
- import { injectStore } from './injectStore'
3
+ import { injectStore } from './store/injectStore'
4
4
  import type {
5
5
  AnyRouter,
6
6
  DeepPartial,
@@ -9,7 +9,6 @@ import type {
9
9
  MakeOptionalSearchParams,
10
10
  MaskOptions,
11
11
  MatchRouteOptions,
12
- NoInfer,
13
12
  RegisteredRouter,
14
13
  ResolveRoute,
15
14
  ToSubOptionsProps,
@@ -31,7 +30,7 @@ export function injectMatchRoute<
31
30
  TRouter extends AnyRouter = RegisteredRouter,
32
31
  >() {
33
32
  const router = injectRouter<TRouter>()
34
- const reactivity = injectStore(router.stores.matchRouteReactivity, (d) => d)
33
+ const reactivity = injectStore(router.stores.matchRouteDeps, (d) => d)
35
34
 
36
35
  return <
37
36
  const TFrom extends string = string,
@@ -41,12 +40,12 @@ export function injectMatchRoute<
41
40
  >(
42
41
  opts: InjectMatchRouteOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,
43
42
  ): Angular.Signal<
44
- false | Expand<ResolveRoute<TRouter, TFrom, NoInfer<TTo>>['types']['allParams']>
43
+ false | Expand<ResolveRoute<TRouter, TFrom, TTo>['types']['allParams']>
45
44
  > => {
46
45
  return Angular.computed(() => {
47
- reactivity()
48
46
  const { pending, caseSensitive, fuzzy, includeSearch, ...rest } = opts
49
47
 
48
+ reactivity()
50
49
  return router.matchRoute(rest as any, {
51
50
  pending,
52
51
  caseSensitive,
@@ -1,7 +1,7 @@
1
1
  import * as Angular from '@angular/core'
2
2
  import { deepEqual } from '@benjavicente/router-core'
3
3
  import { injectRouter } from './injectRouter'
4
- import { injectStore } from './injectStore'
4
+ import { injectStore } from './store/injectStore'
5
5
  import { MATCH_CONTEXT_INJECTOR_TOKEN } from './matchInjectorToken'
6
6
  import type {
7
7
  AnyRouter,
@@ -28,15 +28,15 @@ export function injectMatches<
28
28
  opts?: InjectMatchesBaseOptions<TRouter, TSelected>,
29
29
  ): Angular.Signal<InjectMatchesResult<TRouter, TSelected>> {
30
30
  const router = injectRouter<TRouter>()
31
- const matches = injectStore(router.stores.activeMatchesSnapshot, (value) => {
32
- return value as Array<MakeRouteMatchUnion<TRouter>>
33
- })
34
31
 
35
- return Angular.computed(() => {
36
- const currentMatches = matches()
37
- const result = opts?.select ? opts.select(currentMatches) : currentMatches
38
- return result as InjectMatchesResult<TRouter, TSelected>
39
- }, { equal: deepEqual }) as any
32
+ return injectStore(
33
+ router.stores.matches,
34
+ (currentMatches) => {
35
+ const matches = currentMatches as Array<MakeRouteMatchUnion<TRouter>>
36
+ return opts?.select ? opts.select(matches) : matches
37
+ },
38
+ { equal: deepEqual },
39
+ ) as Angular.Signal<InjectMatchesResult<TRouter, TSelected>>
40
40
  }
41
41
 
42
42
  export function injectParentMatches<
@@ -2,7 +2,7 @@ import { isServer } from '@benjavicente/router-core/isServer'
2
2
  import * as Angular from '@angular/core'
3
3
  import { deepEqual } from '@benjavicente/router-core'
4
4
  import { injectRouter } from './injectRouter'
5
- import { injectStore } from './injectStore'
5
+ import { injectStore } from './store/injectStore'
6
6
  import type {
7
7
  AnyRouter,
8
8
  RegisteredRouter,
@@ -29,25 +29,30 @@ export function injectRouterState<
29
29
  warn: opts?.router === undefined,
30
30
  })
31
31
  const router = opts?.router ?? contextRouter
32
- const state = injectStore(router.stores.__store, (state) => state)
33
32
 
34
33
  // During SSR we render exactly once and do not need reactivity.
35
34
  // Avoid subscribing to the store on the server since the server store
36
35
  // implementation does not provide subscribe() semantics.
37
- const _isServer =
38
- typeof isServer === 'boolean' ? isServer : router.isServer
36
+ const _isServer = isServer ?? router.isServer
39
37
  if (_isServer) {
40
- const state = router.stores.__store.state as RouterState<
38
+ const state = router.stores.__store.get() as RouterState<
41
39
  TRouter['routeTree']
42
40
  >
43
41
  const selected = (
44
42
  opts?.select ? opts.select(state) : state
45
43
  ) as InjectRouterStateResult<TRouter, TSelected>
46
- return (() => selected) as Angular.Signal<InjectRouterStateResult<TRouter, TSelected>>
44
+ return (() => selected) as Angular.Signal<
45
+ InjectRouterStateResult<TRouter, TSelected>
46
+ >
47
+ }
48
+
49
+ if (!opts?.select) {
50
+ return injectStore(router.stores.__store) as Angular.Signal<
51
+ InjectRouterStateResult<TRouter, TSelected>
52
+ >
47
53
  }
48
54
 
49
- return Angular.computed(() => {
50
- const result = opts?.select ? opts.select(state()) : state()
51
- return result as InjectRouterStateResult<TRouter, TSelected>
52
- }, { equal: deepEqual }) as any;
55
+ return injectStore(router.stores.__store, opts.select, {
56
+ equal: deepEqual,
57
+ }) as Angular.Signal<InjectRouterStateResult<TRouter, TSelected>>
53
58
  }
@@ -1,13 +1,13 @@
1
1
  import * as Angular from '@angular/core'
2
2
  import { injectRouter } from '../injectRouter'
3
3
  import { injectRouterState } from '../injectRouterState'
4
- import type { AnyRoute } from '@benjavicente/router-core'
4
+ import type { AnyRoute, AnyRouteMatch } from '@benjavicente/router-core'
5
5
 
6
- export function injectIsCatchingError({
6
+ export function injectCatchingErrorMatch({
7
7
  matchId,
8
8
  }: {
9
9
  matchId: Angular.Signal<string | undefined>
10
- }): Angular.Signal<boolean> {
10
+ }): Angular.Signal<AnyRouteMatch | undefined> {
11
11
  const router = injectRouter()
12
12
 
13
13
  const matches = injectRouterState({
@@ -20,21 +20,33 @@ export function injectIsCatchingError({
20
20
 
21
21
  return Angular.computed(() => {
22
22
  // The child route will handle the error with the default error component.
23
- if (router.options.defaultErrorComponent != null) return false;
23
+ if (router.options.defaultErrorComponent != null) return undefined
24
24
 
25
25
  const startingIndex = matchIndex()
26
- if (startingIndex === -1) return false
26
+ if (startingIndex === -1) return undefined
27
27
  const matchesList = matches()
28
28
 
29
29
  for (let i = startingIndex + 1; i < matchesList.length; i++) {
30
30
  const descendant = matchesList[i]
31
31
  const route = router.routesById[descendant?.routeId] as AnyRoute
32
32
  // Is catched by a child route with an error component.
33
- if (route.options.errorComponent != null) return false
33
+ if (route.options.errorComponent != null) return undefined
34
34
 
35
35
  // Found error status without error component in between.
36
- if (descendant?.status === "error") return true
36
+ if (descendant?.status === 'error') return descendant
37
37
  }
38
- return false
38
+ return undefined
39
+ })
40
+ }
41
+
42
+ export function injectIsCatchingError({
43
+ matchId,
44
+ }: {
45
+ matchId: Angular.Signal<string | undefined>
46
+ }): Angular.Signal<boolean> {
47
+ const catchingErrorMatch = injectCatchingErrorMatch({ matchId })
48
+
49
+ return Angular.computed(() => {
50
+ return catchingErrorMatch() !== undefined
39
51
  })
40
52
  }
@@ -10,7 +10,7 @@ import type { Provider, Type } from '@angular/core'
10
10
 
11
11
  export type RenderValue =
12
12
  | {
13
- key?: string
13
+ key?: unknown
14
14
  component: Type<any> | null | undefined
15
15
  inputs?: Record<string, () => unknown>
16
16
  providers?: Array<Provider>
@@ -57,7 +57,9 @@ export function injectRender(renderValueFn: () => RenderValue): void {
57
57
  function resolvedKey(value: RenderValue) {
58
58
  const component = value?.component
59
59
  if (!value || !component) return []
60
- return [component, value.key]
60
+ return Array.isArray(value.key)
61
+ ? [component, ...value.key]
62
+ : [component, value.key]
61
63
  }
62
64
 
63
65
  function keysAreEqual(a: Array<any>, b: Array<any>) {
package/src/route.ts CHANGED
@@ -53,9 +53,6 @@ declare module '@benjavicente/router-core' {
53
53
  }
54
54
 
55
55
  export interface RootRouteOptionsExtensions {
56
- shellComponent?: Angular.Type<{
57
- children: any
58
- }>
59
56
  }
60
57
 
61
58
  export interface RouteExtensions<
@@ -1,9 +1,10 @@
1
- import * as Angular from '@angular/core'
1
+ import { batch, createAtom } from '@tanstack/store'
2
2
  import {
3
3
  createNonReactiveMutableStore,
4
4
  createNonReactiveReadonlyStore,
5
5
  } from '@benjavicente/router-core'
6
6
  import { isServer } from '@benjavicente/router-core/isServer'
7
+ import type { Readable } from '@tanstack/store'
7
8
  import type {
8
9
  AnyRoute,
9
10
  GetStoreConfig,
@@ -13,9 +14,13 @@ import type {
13
14
  } from '@benjavicente/router-core'
14
15
 
15
16
  declare module '@benjavicente/router-core' {
17
+ export interface RouterReadableStore<TValue> extends Readable<TValue> {}
18
+
16
19
  // eslint-disable-next-line unused-imports/no-unused-vars -- generic must match upstream `RouterStores<TRouteTree>` for augmentation
17
20
  export interface RouterStores<in out TRouteTree extends AnyRoute> {
21
+ /** Maps each active routeId to the matchId of its child in the match tree. */
18
22
  childMatchIdByRouteId: RouterReadableStore<Record<string, string>>
23
+ /** Maps each pending routeId to true for quick lookup. */
19
24
  pendingRouteIds: RouterReadableStore<Record<string, boolean>>
20
25
  }
21
26
  }
@@ -27,68 +32,32 @@ function initRouterStores(
27
32
  ) => RouterReadableStore<TValue>,
28
33
  ) {
29
34
  stores.childMatchIdByRouteId = createReadonlyStore(() => {
30
- const ids = stores.matchesId.state
31
- const result: Record<string, string> = {}
32
-
35
+ const ids = stores.matchesId.get()
36
+ const obj: Record<string, string> = {}
33
37
  for (let i = 0; i < ids.length - 1; i++) {
34
- const matchId = ids[i]
35
- const childId = ids[i + 1]
36
- if (matchId === undefined || childId === undefined) continue
37
- const parentStore = stores.activeMatchStoresById.get(matchId)
38
+ const parentStore = stores.matchStores.get(ids[i]!)
38
39
  if (parentStore?.routeId) {
39
- result[parentStore.routeId] = childId
40
+ obj[parentStore.routeId] = ids[i + 1]!
40
41
  }
41
42
  }
42
-
43
- return result
43
+ return obj
44
44
  })
45
45
 
46
46
  stores.pendingRouteIds = createReadonlyStore(() => {
47
- const ids = stores.pendingMatchesId.state
48
- const result: Record<string, boolean> = {}
49
-
47
+ const ids = stores.pendingIds.get()
48
+ const obj: Record<string, boolean> = {}
50
49
  for (const id of ids) {
51
- const store = stores.pendingMatchStoresById.get(id)
50
+ const store = stores.pendingMatchStores.get(id)
52
51
  if (store?.routeId) {
53
- result[store.routeId] = true
52
+ obj[store.routeId] = true
54
53
  }
55
54
  }
56
-
57
- return result
55
+ return obj
58
56
  })
59
57
  }
60
58
 
61
- function createAngularMutableStore<TValue>(
62
- initialValue: TValue,
63
- ): RouterWritableStore<TValue> {
64
- const signal = Angular.signal(initialValue)
65
-
66
- return {
67
- get state() {
68
- return signal()
69
- },
70
- setState(updater) {
71
- signal.update(updater)
72
- },
73
- }
74
- }
75
-
76
- function createAngularReadonlyStore<TValue>(
77
- read: () => TValue,
78
- ): RouterReadableStore<TValue> {
79
- const computed = Angular.computed(read)
80
-
81
- return {
82
- get state() {
83
- return computed()
84
- },
85
- }
86
- }
87
-
88
59
  export const getStoreFactory: GetStoreConfig = (opts) => {
89
- const useNonReactive =
90
- typeof isServer === 'boolean' ? isServer : !!opts.isServer
91
- if (useNonReactive) {
60
+ if (isServer ?? opts.isServer) {
92
61
  return {
93
62
  createMutableStore: createNonReactiveMutableStore,
94
63
  createReadonlyStore: createNonReactiveReadonlyStore,
@@ -99,9 +68,13 @@ export const getStoreFactory: GetStoreConfig = (opts) => {
99
68
  }
100
69
 
101
70
  return {
102
- createMutableStore: createAngularMutableStore,
103
- createReadonlyStore: createAngularReadonlyStore,
104
- batch: (fn) => fn(),
105
- init: (stores) => initRouterStores(stores, createAngularReadonlyStore),
71
+ createMutableStore: createAtom as <TValue>(
72
+ initialValue: TValue,
73
+ ) => RouterWritableStore<TValue>,
74
+ createReadonlyStore: createAtom as <TValue>(
75
+ read: () => TValue,
76
+ ) => RouterReadableStore<TValue>,
77
+ batch,
78
+ init: (stores) => initRouterStores(stores, createAtom),
106
79
  }
107
80
  }
@@ -0,0 +1,62 @@
1
+ import {
2
+ Injector,
3
+ assertInInjectionContext,
4
+ effect,
5
+ inject,
6
+ linkedSignal,
7
+ runInInjectionContext,
8
+ } from '@angular/core'
9
+ import type { CreateSignalOptions, Signal } from '@angular/core'
10
+
11
+ export interface InjectSelectorOptions<TSelected> extends Omit<
12
+ CreateSignalOptions<TSelected>,
13
+ 'equal'
14
+ > {
15
+ compare?: (a: TSelected, b: TSelected) => boolean
16
+ injector?: Injector
17
+ }
18
+
19
+ export type SelectionSource<T> = {
20
+ get: () => T
21
+ subscribe: (listener: (value: T) => void) => {
22
+ unsubscribe: () => void
23
+ }
24
+ }
25
+
26
+ function resolveInjector(
27
+ fn: (...args: Array<never>) => unknown,
28
+ injector?: Injector,
29
+ ) {
30
+ if (!injector) {
31
+ assertInInjectionContext(fn)
32
+ return inject(Injector)
33
+ }
34
+
35
+ return injector
36
+ }
37
+
38
+ export function injectSelector<TState, TSelected = NoInfer<TState>>(
39
+ source: SelectionSource<TState> | (() => SelectionSource<TState>),
40
+ selector: (state: NoInfer<TState>) => TSelected = (d) =>
41
+ d as unknown as TSelected,
42
+ options?: InjectSelectorOptions<TSelected>,
43
+ ): Signal<TSelected> {
44
+ const injector = resolveInjector(injectSelector, options?.injector)
45
+
46
+ return runInInjectionContext(injector, () => {
47
+ const _source = typeof source === 'function' ? source : () => source
48
+
49
+ const slice = linkedSignal(() => selector(_source().get()), {
50
+ equal: options?.compare,
51
+ })
52
+
53
+ effect((onCleanup) => {
54
+ const { unsubscribe } = _source().subscribe((state) => {
55
+ slice.set(selector(state))
56
+ })
57
+ onCleanup(unsubscribe)
58
+ })
59
+
60
+ return slice.asReadonly()
61
+ })
62
+ }
@@ -0,0 +1,33 @@
1
+ import { injectSelector } from './injectSelector'
2
+ import type { CreateSignalOptions, Injector, Signal } from '@angular/core'
3
+ import type { SelectionSource } from './injectSelector'
4
+
5
+ type CompatibilityInjectStoreOptions<TSelected> =
6
+ CreateSignalOptions<TSelected> & {
7
+ injector?: Injector
8
+ }
9
+
10
+ export function injectStore<TState, TSelected = NoInfer<TState>>(
11
+ store: SelectionSource<TState>,
12
+ selector?: (state: NoInfer<TState>) => TSelected,
13
+ options?: CompatibilityInjectStoreOptions<TSelected>,
14
+ ): Signal<TSelected>
15
+ export function injectStore<TState, TSelected = NoInfer<TState>>(
16
+ store: SelectionSource<TState> | (() => SelectionSource<TState>),
17
+ selector?: (state: NoInfer<TState>) => TSelected,
18
+ options?: CompatibilityInjectStoreOptions<TSelected>,
19
+ ): Signal<TSelected>
20
+ export function injectStore<TState, TSelected = NoInfer<TState>>(
21
+ store: SelectionSource<TState> | (() => SelectionSource<TState>),
22
+ selector: (state: NoInfer<TState>) => TSelected = (d) =>
23
+ d as unknown as TSelected,
24
+ options?: CompatibilityInjectStoreOptions<TSelected>,
25
+ ): Signal<TSelected> {
26
+ const { equal, injector, ...signalOptions } = options ?? {}
27
+
28
+ return injectSelector(store, selector, {
29
+ ...signalOptions,
30
+ compare: equal,
31
+ injector,
32
+ })
33
+ }