@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.
Files changed (34) hide show
  1. package/build/esm2022/inject-is-fetching.mjs +2 -2
  2. package/build/esm2022/inject-is-mutating.mjs +2 -2
  3. package/build/esm2022/inject-mutation.mjs +7 -7
  4. package/build/esm2022/inject-queries.mjs +2 -2
  5. package/build/esm2022/inject-query-client.mjs +2 -2
  6. package/build/esm2022/inject-query.mjs +2 -2
  7. package/build/esm2022/signal-proxy.mjs +1 -1
  8. package/build/esm2022/types.mjs +1 -1
  9. package/build/esm2022/util/assert-injector/assert-injector.mjs +19 -0
  10. package/build/esm2022/util/create-injection-token/create-injection-token.mjs +60 -0
  11. package/build/fesm2022/tanstack-angular-query-experimental.mjs +119 -46
  12. package/build/fesm2022/tanstack-angular-query-experimental.mjs.map +1 -1
  13. package/build/signal-proxy.d.ts +1 -2
  14. package/build/types.d.ts +4 -7
  15. package/build/util/assert-injector/assert-injector.d.ts +54 -0
  16. package/build/util/create-injection-token/create-injection-token.d.ts +52 -0
  17. package/package.json +1 -2
  18. package/src/__tests__/inject-is-mutating.test.ts +1 -5
  19. package/src/__tests__/inject-mutation.test.ts +276 -24
  20. package/src/__tests__/inject-query.test.ts +3 -3
  21. package/src/__tests__/test-utils.ts +36 -0
  22. package/src/inject-is-fetching.ts +1 -1
  23. package/src/inject-is-mutating.ts +1 -1
  24. package/src/inject-mutation.ts +7 -8
  25. package/src/inject-queries.ts +1 -1
  26. package/src/inject-query-client.ts +1 -1
  27. package/src/inject-query.ts +1 -1
  28. package/src/signal-proxy.ts +1 -1
  29. package/src/test-setup.ts +2 -3
  30. package/src/types.ts +4 -9
  31. package/src/util/assert-injector/assert-injector.test.ts +72 -0
  32. package/src/util/assert-injector/assert-injector.ts +79 -0
  33. package/src/util/create-injection-token/create-injection-token.test.ts +30 -0
  34. 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
+ }