@tanstack/angular-query-experimental 5.15.5 → 5.16.1
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/build/esm2022/inject-is-fetching.mjs +2 -2
- package/build/esm2022/inject-is-mutating.mjs +2 -2
- package/build/esm2022/inject-mutation.mjs +7 -7
- package/build/esm2022/inject-queries.mjs +2 -2
- package/build/esm2022/inject-query-client.mjs +2 -2
- package/build/esm2022/inject-query.mjs +2 -2
- package/build/esm2022/signal-proxy.mjs +1 -1
- package/build/esm2022/types.mjs +1 -1
- package/build/esm2022/util/assert-injector/assert-injector.mjs +19 -0
- package/build/esm2022/util/create-injection-token/create-injection-token.mjs +60 -0
- package/build/fesm2022/tanstack-angular-query-experimental.mjs +119 -46
- package/build/fesm2022/tanstack-angular-query-experimental.mjs.map +1 -1
- package/build/signal-proxy.d.ts +1 -2
- package/build/types.d.ts +4 -7
- package/build/util/assert-injector/assert-injector.d.ts +54 -0
- package/build/util/create-injection-token/create-injection-token.d.ts +52 -0
- package/package.json +1 -2
- package/src/__tests__/inject-is-mutating.test.ts +1 -5
- package/src/__tests__/inject-mutation.test.ts +276 -24
- package/src/__tests__/inject-query.test.ts +3 -3
- package/src/__tests__/test-utils.ts +36 -0
- package/src/inject-is-fetching.ts +1 -1
- package/src/inject-is-mutating.ts +1 -1
- package/src/inject-mutation.ts +7 -8
- package/src/inject-queries.ts +1 -1
- package/src/inject-query-client.ts +1 -1
- package/src/inject-query.ts +1 -1
- package/src/signal-proxy.ts +1 -1
- package/src/test-setup.ts +2 -3
- package/src/types.ts +4 -9
- package/src/util/assert-injector/assert-injector.test.ts +72 -0
- package/src/util/assert-injector/assert-injector.ts +79 -0
- package/src/util/create-injection-token/create-injection-token.test.ts +30 -0
- package/src/util/create-injection-token/create-injection-token.ts +184 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The code in this file is adapted from NG Extension Platform at https://ngxtension.netlify.app.
|
|
3
|
+
*
|
|
4
|
+
* Original Author: Chau Tran
|
|
5
|
+
*
|
|
6
|
+
* NG Extension Platform is an open-source project licensed under the MIT license.
|
|
7
|
+
*
|
|
8
|
+
* For more information about the original code, see
|
|
9
|
+
* https://github.com/nartc/ngxtension-platform
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
Injector,
|
|
14
|
+
assertInInjectionContext,
|
|
15
|
+
inject,
|
|
16
|
+
runInInjectionContext,
|
|
17
|
+
} from '@angular/core'
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* `assertInjector` extends `assertInInjectionContext` with an optional `Injector`
|
|
21
|
+
* After assertion, `assertInjector` runs the `runner` function with the guaranteed `Injector`
|
|
22
|
+
* whether it is the default `Injector` within the current **Injection Context**
|
|
23
|
+
* or the custom `Injector` that was passed in.
|
|
24
|
+
*
|
|
25
|
+
* @template {() => any} Runner - Runner is a function that can return anything
|
|
26
|
+
* @param {Function} fn - the Function to pass in `assertInInjectionContext`
|
|
27
|
+
* @param {Injector | undefined | null} injector - the optional "custom" Injector
|
|
28
|
+
* @param {Runner} runner - the runner fn
|
|
29
|
+
* @returns {ReturnType<Runner>} result - returns the result of the Runner
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* function injectValue(injector?: Injector) {
|
|
34
|
+
* return assertInjector(injectValue, injector, () => 'value');
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* injectValue(); // string
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export function assertInjector<Runner extends () => any>(
|
|
41
|
+
fn: Function,
|
|
42
|
+
injector: Injector | undefined | null,
|
|
43
|
+
runner: Runner,
|
|
44
|
+
): ReturnType<Runner>
|
|
45
|
+
/**
|
|
46
|
+
* `assertInjector` extends `assertInInjectionContext` with an optional `Injector`
|
|
47
|
+
* After assertion, `assertInjector` returns a guaranteed `Injector` whether it is the default `Injector`
|
|
48
|
+
* within the current **Injection Context** or the custom `Injector` that was passed in.
|
|
49
|
+
*
|
|
50
|
+
* @param {Function} fn - the Function to pass in `assertInInjectionContext`
|
|
51
|
+
* @param {Injector | undefined | null} injector - the optional "custom" Injector
|
|
52
|
+
* @returns Injector
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* function injectDestroy(injector?: Injector) {
|
|
57
|
+
* injector = assertInjector(injectDestroy, injector);
|
|
58
|
+
*
|
|
59
|
+
* return runInInjectionContext(injector, () => {
|
|
60
|
+
* // code
|
|
61
|
+
* })
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export function assertInjector(
|
|
66
|
+
fn: Function,
|
|
67
|
+
injector: Injector | undefined | null,
|
|
68
|
+
): Injector
|
|
69
|
+
export function assertInjector(
|
|
70
|
+
fn: Function,
|
|
71
|
+
injector: Injector | undefined | null,
|
|
72
|
+
runner?: () => any,
|
|
73
|
+
) {
|
|
74
|
+
!injector && assertInInjectionContext(fn)
|
|
75
|
+
const assertedInjector = injector ?? inject(Injector)
|
|
76
|
+
|
|
77
|
+
if (!runner) return assertedInjector
|
|
78
|
+
return runInInjectionContext(assertedInjector, runner)
|
|
79
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The code in this file is adapted from NG Extension Platform at https://ngxtension.netlify.app.
|
|
3
|
+
*
|
|
4
|
+
* Original Author: Chau Tran
|
|
5
|
+
*
|
|
6
|
+
* NG Extension Platform is an open-source project licensed under the MIT license.
|
|
7
|
+
*
|
|
8
|
+
* For more information about the original code, see
|
|
9
|
+
* https://github.com/nartc/ngxtension-platform
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { TestBed } from '@angular/core/testing'
|
|
13
|
+
import { createNoopInjectionToken } from './create-injection-token'
|
|
14
|
+
|
|
15
|
+
describe(createNoopInjectionToken.name, () => {
|
|
16
|
+
describe('given an injection token', () => {
|
|
17
|
+
const [injectFn, provideFn] = createNoopInjectionToken<number, true>(
|
|
18
|
+
'noop',
|
|
19
|
+
{ multi: true },
|
|
20
|
+
)
|
|
21
|
+
it('then work properly', () => {
|
|
22
|
+
TestBed.configureTestingModule({
|
|
23
|
+
providers: [provideFn(1), provideFn(() => 2)],
|
|
24
|
+
}).runInInjectionContext(() => {
|
|
25
|
+
const values = injectFn()
|
|
26
|
+
expect(values).toEqual([1, 2])
|
|
27
|
+
})
|
|
28
|
+
})
|
|
29
|
+
})
|
|
30
|
+
})
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The code in this file is adapted from NG Extension Platform at https://ngxtension.netlify.app.
|
|
3
|
+
*
|
|
4
|
+
* Original Author: Chau Tran
|
|
5
|
+
*
|
|
6
|
+
* NG Extension Platform is an open-source project licensed under the MIT license.
|
|
7
|
+
*
|
|
8
|
+
* For more information about the original code, see
|
|
9
|
+
* https://github.com/nartc/ngxtension-platform
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
type EnvironmentProviders,
|
|
14
|
+
type FactoryProvider,
|
|
15
|
+
type Host,
|
|
16
|
+
type InjectOptions,
|
|
17
|
+
InjectionToken,
|
|
18
|
+
type Injector,
|
|
19
|
+
type Optional,
|
|
20
|
+
type Provider,
|
|
21
|
+
type Self,
|
|
22
|
+
type SkipSelf,
|
|
23
|
+
type Type,
|
|
24
|
+
inject,
|
|
25
|
+
runInInjectionContext,
|
|
26
|
+
} from '@angular/core'
|
|
27
|
+
import { assertInjector } from '../assert-injector/assert-injector'
|
|
28
|
+
|
|
29
|
+
type CreateInjectionTokenDep<TTokenType> =
|
|
30
|
+
| Type<TTokenType>
|
|
31
|
+
// NOTE: we don't have an AbstractType
|
|
32
|
+
| (abstract new (...args: Array<any>) => TTokenType)
|
|
33
|
+
| InjectionToken<TTokenType>
|
|
34
|
+
|
|
35
|
+
type CreateInjectionTokenDeps<
|
|
36
|
+
TFactory extends (...args: Array<any>) => any,
|
|
37
|
+
TFactoryDeps extends Parameters<TFactory> = Parameters<TFactory>,
|
|
38
|
+
> = {
|
|
39
|
+
[Index in keyof TFactoryDeps]:
|
|
40
|
+
| CreateInjectionTokenDep<TFactoryDeps[Index]>
|
|
41
|
+
| [
|
|
42
|
+
...modifiers: Array<Optional | Self | SkipSelf | Host>,
|
|
43
|
+
token: CreateInjectionTokenDep<TFactoryDeps[Index]>,
|
|
44
|
+
]
|
|
45
|
+
} & { length: TFactoryDeps['length'] }
|
|
46
|
+
|
|
47
|
+
type CreateInjectionTokenOptions<
|
|
48
|
+
TFactory extends (...args: Array<any>) => any,
|
|
49
|
+
TFactoryDeps extends Parameters<TFactory> = Parameters<TFactory>,
|
|
50
|
+
> =
|
|
51
|
+
// this means TFunction has no parameters
|
|
52
|
+
(TFactoryDeps[0] extends undefined
|
|
53
|
+
? { deps?: never }
|
|
54
|
+
: { deps: CreateInjectionTokenDeps<TFactory, TFactoryDeps> }) & {
|
|
55
|
+
isRoot?: boolean
|
|
56
|
+
multi?: boolean
|
|
57
|
+
token?: InjectionToken<ReturnType<TFactory>>
|
|
58
|
+
extraProviders?: Provider | EnvironmentProviders
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
type CreateProvideFnOptions<
|
|
62
|
+
TFactory extends (...args: Array<any>) => any,
|
|
63
|
+
TFactoryDeps extends Parameters<TFactory> = Parameters<TFactory>,
|
|
64
|
+
> = Pick<
|
|
65
|
+
CreateInjectionTokenOptions<TFactory, TFactoryDeps>,
|
|
66
|
+
'deps' | 'extraProviders' | 'multi'
|
|
67
|
+
>
|
|
68
|
+
|
|
69
|
+
type InjectFn<TFactoryReturn> = {
|
|
70
|
+
(): TFactoryReturn
|
|
71
|
+
(
|
|
72
|
+
injectOptions: InjectOptions & { optional?: false } & {
|
|
73
|
+
injector?: Injector
|
|
74
|
+
},
|
|
75
|
+
): TFactoryReturn
|
|
76
|
+
(
|
|
77
|
+
injectOptions: InjectOptions & { injector?: Injector },
|
|
78
|
+
): TFactoryReturn | null
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
type ProvideFn<
|
|
82
|
+
TNoop extends boolean,
|
|
83
|
+
TFactoryReturn,
|
|
84
|
+
TReturn = TFactoryReturn extends Array<infer Item> ? Item : TFactoryReturn,
|
|
85
|
+
> = (TNoop extends true
|
|
86
|
+
? (value: TReturn | (() => TReturn)) => Provider
|
|
87
|
+
: () => Provider) &
|
|
88
|
+
(TReturn extends Function
|
|
89
|
+
? (value: TReturn | (() => TReturn), isFunctionValue: boolean) => Provider
|
|
90
|
+
: (value: TReturn | (() => TReturn)) => Provider)
|
|
91
|
+
|
|
92
|
+
type CreateInjectionTokenReturn<
|
|
93
|
+
TFactoryReturn,
|
|
94
|
+
TNoop extends boolean = false,
|
|
95
|
+
> = [
|
|
96
|
+
InjectFn<TFactoryReturn>,
|
|
97
|
+
ProvideFn<TNoop, TFactoryReturn>,
|
|
98
|
+
InjectionToken<TFactoryReturn>,
|
|
99
|
+
() => Provider,
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
function createInjectFn<TValue>(token: InjectionToken<TValue>) {
|
|
103
|
+
return function (
|
|
104
|
+
this: Function,
|
|
105
|
+
{
|
|
106
|
+
injector,
|
|
107
|
+
...injectOptions
|
|
108
|
+
}: InjectOptions & { injector?: Injector } = {},
|
|
109
|
+
) {
|
|
110
|
+
injector = assertInjector(this, injector)
|
|
111
|
+
return runInInjectionContext(injector, () =>
|
|
112
|
+
inject(token, injectOptions as InjectOptions),
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function createProvideFn<
|
|
118
|
+
TValue,
|
|
119
|
+
TFactory extends (...args: Array<any>) => any = (
|
|
120
|
+
...args: Array<any>
|
|
121
|
+
) => TValue,
|
|
122
|
+
TFactoryDeps extends Parameters<TFactory> = Parameters<TFactory>,
|
|
123
|
+
>(
|
|
124
|
+
token: InjectionToken<TValue>,
|
|
125
|
+
factory: (...args: Array<any>) => TValue,
|
|
126
|
+
opts: CreateProvideFnOptions<TFactory, TFactoryDeps> = {},
|
|
127
|
+
) {
|
|
128
|
+
const { deps = [], multi = false, extraProviders = [] } = opts
|
|
129
|
+
return (value?: TValue | (() => TValue), isFunctionValue = false) => {
|
|
130
|
+
let provider: Provider
|
|
131
|
+
if (typeof value !== 'undefined') {
|
|
132
|
+
// eslint-disable-next-line no-shadow
|
|
133
|
+
const factory =
|
|
134
|
+
typeof value === 'function'
|
|
135
|
+
? isFunctionValue
|
|
136
|
+
? () => value
|
|
137
|
+
: value
|
|
138
|
+
: () => value
|
|
139
|
+
|
|
140
|
+
provider = {
|
|
141
|
+
provide: token,
|
|
142
|
+
useFactory: factory,
|
|
143
|
+
multi,
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
provider = {
|
|
147
|
+
provide: token,
|
|
148
|
+
useFactory: factory,
|
|
149
|
+
deps: deps as FactoryProvider['deps'],
|
|
150
|
+
multi,
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return [extraProviders, provider]
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export function createNoopInjectionToken<
|
|
159
|
+
TValue,
|
|
160
|
+
TMulti extends boolean = false,
|
|
161
|
+
TOptions = Pick<
|
|
162
|
+
CreateInjectionTokenOptions<() => void, []>,
|
|
163
|
+
'extraProviders'
|
|
164
|
+
> &
|
|
165
|
+
(TMulti extends true ? { multi: true } : Record<string, never>),
|
|
166
|
+
>(description: string, options?: TOptions) {
|
|
167
|
+
type TReturn = TMulti extends true ? Array<TValue> : TValue
|
|
168
|
+
|
|
169
|
+
const token =
|
|
170
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
171
|
+
(options as CreateInjectionTokenOptions<() => void, []>)?.token ||
|
|
172
|
+
new InjectionToken<TReturn>(description)
|
|
173
|
+
return [
|
|
174
|
+
createInjectFn(token) as CreateInjectionTokenReturn<TReturn, true>[0],
|
|
175
|
+
createProvideFn(
|
|
176
|
+
token,
|
|
177
|
+
() => null!,
|
|
178
|
+
(options || {}) as CreateProvideFnOptions<() => void, []>,
|
|
179
|
+
) as CreateInjectionTokenReturn<TReturn, true>[1],
|
|
180
|
+
token,
|
|
181
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
182
|
+
() => {},
|
|
183
|
+
] as CreateInjectionTokenReturn<TReturn, true>
|
|
184
|
+
}
|