@effect-app/vue 4.0.0-beta.17 → 4.0.0-beta.170

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 (96) hide show
  1. package/CHANGELOG.md +1090 -0
  2. package/dist/commander.d.ts +370 -0
  3. package/dist/commander.d.ts.map +1 -0
  4. package/dist/commander.js +591 -0
  5. package/dist/confirm.d.ts +19 -0
  6. package/dist/confirm.d.ts.map +1 -0
  7. package/dist/confirm.js +24 -0
  8. package/dist/errorReporter.d.ts +4 -4
  9. package/dist/errorReporter.d.ts.map +1 -1
  10. package/dist/errorReporter.js +12 -18
  11. package/dist/form.d.ts +13 -4
  12. package/dist/form.d.ts.map +1 -1
  13. package/dist/form.js +41 -12
  14. package/dist/index.d.ts +1 -1
  15. package/dist/intl.d.ts +15 -0
  16. package/dist/intl.d.ts.map +1 -0
  17. package/dist/intl.js +9 -0
  18. package/dist/lib.d.ts +8 -9
  19. package/dist/lib.d.ts.map +1 -1
  20. package/dist/lib.js +34 -7
  21. package/dist/makeClient.d.ts +119 -277
  22. package/dist/makeClient.d.ts.map +1 -1
  23. package/dist/makeClient.js +155 -359
  24. package/dist/makeContext.d.ts +1 -1
  25. package/dist/makeContext.d.ts.map +1 -1
  26. package/dist/makeIntl.d.ts +1 -1
  27. package/dist/makeIntl.d.ts.map +1 -1
  28. package/dist/makeUseCommand.d.ts +8 -0
  29. package/dist/makeUseCommand.d.ts.map +1 -0
  30. package/dist/makeUseCommand.js +13 -0
  31. package/dist/mutate.d.ts +4 -4
  32. package/dist/mutate.d.ts.map +1 -1
  33. package/dist/mutate.js +7 -7
  34. package/dist/query.d.ts +11 -15
  35. package/dist/query.d.ts.map +1 -1
  36. package/dist/query.js +19 -27
  37. package/dist/routeParams.d.ts +1 -1
  38. package/dist/runtime.d.ts +5 -2
  39. package/dist/runtime.d.ts.map +1 -1
  40. package/dist/runtime.js +27 -17
  41. package/dist/toast.d.ts +46 -0
  42. package/dist/toast.d.ts.map +1 -0
  43. package/dist/toast.js +32 -0
  44. package/dist/withToast.d.ts +26 -0
  45. package/dist/withToast.d.ts.map +1 -0
  46. package/dist/withToast.js +49 -0
  47. package/eslint.config.mjs +2 -2
  48. package/package.json +48 -48
  49. package/src/{experimental/commander.ts → commander.ts} +930 -255
  50. package/src/{experimental/confirm.ts → confirm.ts} +10 -14
  51. package/src/errorReporter.ts +60 -72
  52. package/src/form.ts +55 -16
  53. package/src/intl.ts +12 -0
  54. package/src/lib.ts +50 -13
  55. package/src/makeClient.ts +454 -1023
  56. package/src/{experimental/makeUseCommand.ts → makeUseCommand.ts} +3 -3
  57. package/src/mutate.ts +40 -32
  58. package/src/query.ts +39 -50
  59. package/src/runtime.ts +39 -18
  60. package/src/{experimental/toast.ts → toast.ts} +11 -25
  61. package/src/{experimental/withToast.ts → withToast.ts} +15 -6
  62. package/test/Mutation.test.ts +130 -10
  63. package/test/dist/form.test.d.ts.map +1 -1
  64. package/test/dist/lib.test.d.ts.map +1 -0
  65. package/test/dist/stubs.d.ts +2123 -118
  66. package/test/dist/stubs.d.ts.map +1 -1
  67. package/test/dist/stubs.js +77 -23
  68. package/test/form-validation-errors.test.ts +23 -19
  69. package/test/form.test.ts +20 -2
  70. package/test/lib.test.ts +240 -0
  71. package/test/makeClient.test.ts +209 -38
  72. package/test/stubs.ts +112 -40
  73. package/tsconfig.json +0 -1
  74. package/tsconfig.json.bak +2 -2
  75. package/tsconfig.src.json +34 -34
  76. package/tsconfig.test.json +2 -2
  77. package/vitest.config.ts +5 -5
  78. package/dist/experimental/commander.d.ts +0 -359
  79. package/dist/experimental/commander.d.ts.map +0 -1
  80. package/dist/experimental/commander.js +0 -557
  81. package/dist/experimental/confirm.d.ts +0 -19
  82. package/dist/experimental/confirm.d.ts.map +0 -1
  83. package/dist/experimental/confirm.js +0 -28
  84. package/dist/experimental/intl.d.ts +0 -16
  85. package/dist/experimental/intl.d.ts.map +0 -1
  86. package/dist/experimental/intl.js +0 -5
  87. package/dist/experimental/makeUseCommand.d.ts +0 -8
  88. package/dist/experimental/makeUseCommand.d.ts.map +0 -1
  89. package/dist/experimental/makeUseCommand.js +0 -13
  90. package/dist/experimental/toast.d.ts +0 -47
  91. package/dist/experimental/toast.d.ts.map +0 -1
  92. package/dist/experimental/toast.js +0 -41
  93. package/dist/experimental/withToast.d.ts +0 -25
  94. package/dist/experimental/withToast.d.ts.map +0 -1
  95. package/dist/experimental/withToast.js +0 -45
  96. package/src/experimental/intl.ts +0 -9
@@ -1,95 +1,266 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { type Effect } from "effect-app"
3
- import { Something, useClient, useExperimental } from "./stubs.js"
4
-
5
- it.skip("works2", () => {
6
- const { legacy } = useClient()
7
- const n = legacy.useQuery({
8
- Request: null as any,
9
- handler: null as any as (a: string) => Effect.Effect<number>,
10
- id: "id"
2
+ import { S } from "effect-app"
3
+ import { configureInvalidation, makeQueryKey } from "effect-app/client"
4
+ import * as Exit from "effect/Exit"
5
+ import { Something, SomethingElse, SomethingElseReq, SomethingReq, useClient, useExperimental } from "./stubs.js"
6
+
7
+ const somethingInvalidationResources = {
8
+ Something: {
9
+ GetSomething2: Something.GetSomething2,
10
+ GetSomething2WithDependencies: Something.GetSomething2WithDependencies,
11
+ GetSomething3: Something.GetSomething3
12
+ }
13
+ }
14
+
15
+ it("TaggedRequestFor .moduleName and request .id / .moduleName", () => {
16
+ expectTypeOf(SomethingReq.moduleName).toEqualTypeOf<"Something">()
17
+ expectTypeOf(SomethingElseReq.moduleName).toEqualTypeOf<"SomethingElse">()
18
+
19
+ expectTypeOf(Something.GetSomething2.moduleName).toEqualTypeOf<"Something">()
20
+ expectTypeOf(Something.GetSomething2.id).toEqualTypeOf<"Something.GetSomething2">()
21
+ expectTypeOf(Something.GetSomething2.type).toEqualTypeOf<"query">()
22
+ expectTypeOf(Something.DoSomething.type).toEqualTypeOf<"command">()
23
+
24
+ expectTypeOf(SomethingElse.GetSomething2.moduleName).toEqualTypeOf<"SomethingElse">()
25
+ expectTypeOf(SomethingElse.GetSomething2.id).toEqualTypeOf<"SomethingElse.GetSomething2">()
26
+
27
+ const invalidates = configureInvalidation<{
28
+ Something: typeof Something
29
+ SomethingElse: typeof SomethingElse
30
+ }>()((queryKey, { Something, SomethingElse }) => [
31
+ { filters: { queryKey } },
32
+ { filters: { queryKey: makeQueryKey(Something.GetSomething2) } },
33
+ { filters: { queryKey: makeQueryKey(SomethingElse.GetSomething2) } }
34
+ ])
35
+
36
+ expectTypeOf(invalidates.invalidatesQueries).toBeFunction()
37
+ configureInvalidation<{ Something: typeof Something }>()((_queryKey, { Something }) => {
38
+ // @ts-expect-error commands are intentionally excluded from configured resources
39
+ void Something.DoSomething
40
+ return []
11
41
  })
12
42
 
13
- const [, z] = n("a")
43
+ const { clientFor } = useClient()
44
+ const client = clientFor(
45
+ Something,
46
+ undefined,
47
+ somethingInvalidationResources
48
+ )
49
+
50
+ // @ts-expect-error invalidation resources should be required when any command configures them
51
+ clientFor(Something)
52
+
53
+ // @ts-expect-error invalidation resources for this module reject extra top-level resources
54
+ clientFor(Something, undefined, { ...somethingInvalidationResources, SomethingElse })
55
+
56
+ const doSomethingInvalidation = client.DoSomething.Request.config["invalidatesQueries"]
57
+ if (doSomethingInvalidation) {
58
+ const entries = doSomethingInvalidation(
59
+ ["$Something"],
60
+ somethingInvalidationResources,
61
+ { id: "abc" },
62
+ Exit.succeed(123)
63
+ )
64
+ expect(Array.isArray(entries)).toBe(true)
65
+ }
66
+
67
+ const SomethingCommand = SomethingReq.Command
68
+
69
+ class TypeInferenceWithSuccess extends SomethingCommand<TypeInferenceWithSuccess>()("TypeInferenceWithSuccess", {
70
+ id: S.String
71
+ }, {
72
+ success: S.FiniteFromString
73
+ }, (_queryKey, _resources, input, result) => {
74
+ expectTypeOf(input).toEqualTypeOf<{ readonly id: string }>()
75
+ expectTypeOf(result).toEqualTypeOf<Exit.Exit<number, never>>()
76
+ return []
77
+ }) {}
78
+ void TypeInferenceWithSuccess
79
+
80
+ class TypeInferenceWithoutSuccess extends SomethingCommand<TypeInferenceWithoutSuccess>()(
81
+ "TypeInferenceWithoutSuccess",
82
+ {
83
+ id: S.String
84
+ },
85
+ {},
86
+ (_queryKey, _resources, input, result) => {
87
+ expectTypeOf(input).toEqualTypeOf<{ readonly id: string }>()
88
+ expectTypeOf(result).toEqualTypeOf<Exit.Exit<void, never>>()
89
+ return []
90
+ }
91
+ ) {}
92
+ void TypeInferenceWithoutSuccess
93
+
94
+ type MixedResources = {
95
+ Something: typeof Something
96
+ Misc: {
97
+ value: number
98
+ GetSomething2: typeof Something.GetSomething2
99
+ }
100
+ }
101
+
102
+ class TypeInferenceResourceFiltering extends SomethingCommand<
103
+ TypeInferenceResourceFiltering,
104
+ MixedResources
105
+ >()("TypeInferenceResourceFiltering", {
106
+ id: S.String
107
+ }, {
108
+ success: S.FiniteFromString
109
+ }, (_queryKey, resources, _input, _result) => {
110
+ expectTypeOf(resources.Something.GetSomething2).toEqualTypeOf<typeof Something.GetSomething2>()
111
+ expectTypeOf(resources.Misc.GetSomething2).toEqualTypeOf<typeof Something.GetSomething2>()
112
+
113
+ // @ts-expect-error commands must be filtered from invalidation resources
114
+ void resources.Something.DoSomething
115
+ // @ts-expect-error non-query values must be filtered from invalidation resources
116
+ void resources.Misc.value
117
+
118
+ return []
119
+ }) {}
120
+ void TypeInferenceResourceFiltering
121
+
122
+ type WithSuccessInvalidation = NonNullable<typeof TypeInferenceWithSuccess.config.invalidatesQueries>
123
+ // @ts-expect-error input should be required when command payload is non-empty
124
+ ;((_queryKey, _resources) => []) satisfies WithSuccessInvalidation
125
+ })
126
+
127
+ it.skip("query type tests", () => {
128
+ const { clientFor } = useClient()
129
+ const client = clientFor(
130
+ Something,
131
+ () => ({
132
+ GetSomething2WithDependencies: (queryKey) => [
133
+ { filters: { queryKey } },
134
+ {
135
+ filters: {
136
+ queryKey: makeQueryKey(
137
+ SomethingElse
138
+ .GetSomething2
139
+ )
140
+ }
141
+ }
142
+ ]
143
+ }),
144
+ somethingInvalidationResources
145
+ )
146
+
147
+ const q = client.GetSomething2.query
148
+
149
+ const [, z] = q({ id: "a" })
14
150
  const valz = z.value
15
151
  expectTypeOf(valz).toEqualTypeOf<number | undefined>()
16
152
 
17
- const [, a] = n("a", { placeholderData: () => 123 })
153
+ const [, a] = q({ id: "a" }, { placeholderData: () => 123 })
18
154
  const val1 = a.value
19
155
  expectTypeOf(val1).toEqualTypeOf<number>()
20
156
 
21
- const [, bbbb] = n("a", { select: (data) => data.toString() })
157
+ const [, bbbb] = q({ id: "a" }, { select: (data) => data.toString() })
22
158
  const val = bbbb.value
23
159
  expectTypeOf(val).toEqualTypeOf<string | undefined>()
24
160
 
25
- const [, ccc] = n("a", { placeholderData: () => 123, select: (data) => data.toString() })
161
+ const [, ccc] = q({ id: "a" }, { placeholderData: () => 123, select: (data) => data.toString() })
26
162
  const val2 = ccc.value
27
163
  expectTypeOf(val2).toEqualTypeOf<string>()
28
164
 
29
- const [, ddd] = n("a", { initialData: 123, select: (data) => data.toString() })
165
+ const [, ddd] = q({ id: "a" }, { initialData: 123, select: (data) => data.toString() })
30
166
  const val3 = ddd.value
31
167
  expectTypeOf(val3).toEqualTypeOf<string>()
32
168
 
33
- const [, eee] = n("a", { initialData: 123, placeholderData: () => 123, select: (data) => data.toString() })
169
+ const [, eee] = q({ id: "a" }, { initialData: 123, placeholderData: () => 123, select: (data) => data.toString() })
34
170
  const val4 = eee.value
35
171
  expectTypeOf(val4).toEqualTypeOf<string>()
36
172
  })
37
173
 
38
174
  it.skip("works", () => {
39
- const { clientFor, legacy } = useClient()
40
- const client = clientFor(Something)
175
+ const { clientFor } = useClient()
176
+ const client = clientFor(Something, undefined, somethingInvalidationResources)
41
177
  const Command = useExperimental()
42
178
 
43
179
  // just for jsdoc / type testing.
44
- const a0 = client.GetSomething2(null as any)
45
- const a00 = client.GetSomething2.mutate(null as any)
180
+ const a0 = client.GetSomething2.request(null as any)
181
+ const a00 = client.DoSomething.mutate(null as any)
46
182
  const a = client.GetSomething2.suspense(null as any)
47
183
  const b = client.GetSomething2.query(null as any)
48
184
 
49
- const c0 = legacy.useSafeMutation(null as any)
50
- const c = legacy.useQuery(null as any)
51
- const d = legacy.useSuspenseQuery(null as any)
185
+ const de = client.GetSomething3.handler(null as any)
186
+ const de2 = client.GetSomething3.handler({ id: null })
52
187
 
188
+ // @ts-expect-error query requests no longer expose command helpers
53
189
  const e = client.GetSomething2.wrap(null as any)
190
+ // @ts-expect-error query requests no longer expose command helpers
54
191
  const f = client.GetSomething2.fn(null as any)
55
192
 
56
- // @ts-expect-error dependencies required that are not provided
57
- const e0 = client.GetSomething2WithDependencies.wrap().handle // not available as we require dependencies not provided by the runtime
58
- // @ts-expect-error dependencies required that are not provided
59
- const e000 = Command.wrap(client.GetSomething2WithDependencies)().handle // not available as we require dependencies not provided by the runtime
60
- const e00 = client.GetSomething2WithDependencies.wrap((_) => _ as Effect.Effect<number, never, never>).handle(
61
- null as any
62
- )
63
- const e0000 =
64
- Command.wrap(client.GetSomething2WithDependencies)((_) => _ as Effect.Effect<number, never, never>).handle
193
+ // @ts-expect-error query requests no longer expose command helpers
194
+ const e0 = client.GetSomething2WithDependencies.wrap
195
+ // @ts-expect-error query request does not match Command.wrap mutation signature
196
+ const e000 = Command.wrap(client.GetSomething2WithDependencies)
197
+ const e00 = client.GetSomething2WithDependencies.request(null as any)
65
198
  // @ts-expect-error dependencies required that are not provided
66
199
  const e1 = client.GetSomething2WithDependencies.suspense(null as any)
67
200
  // @ts-expect-error dependencies required that are not provided
68
201
  const e2 = client.GetSomething2WithDependencies.query(null as any)
202
+ // @ts-expect-error query requests no longer expose command helpers
69
203
  const f0 = client.GetSomething2WithDependencies.fn(null as any)
70
204
 
71
- const g = client.GetSomething2.mutate.wrap(null as any)
72
- const h = client.GetSomething2.mutate.fn(null as any)
205
+ const g0 = client.DoSomething.wrap(null as any)
206
+ const g = client.DoSomething.mutate.wrap(null as any)
207
+ const g1 = client.DoSomething.mutate.project(S.String)
208
+ const g2 = g1(null as any)
209
+ const g3 = g1.wrap(null as any)
210
+ const g4 = client.helpers.doSomethingMutation.project(S.String)
211
+ const g5 = g4(null as any)
212
+ const g6 = g4.wrap(null as any)
213
+ // @ts-expect-error mutate no longer exposes fn, use client.DoSomething.fn
214
+ const h = client.DoSomething.mutate.fn(null as any)
215
+
216
+ // projection
217
+ // GetSomething2 uses FiniteFromString, that means Codec is String -> Number
218
+ // when we project that to S.String, it should work as the encoded shapes are identical
219
+ // aka, when we project, we skip decoding with the original codec, and instead use the provided one
220
+ // we have to make sure the Encoded shape of the provided projection schema matches the Encoded Shape of the original codec.
221
+ const projected = client.GetSomething2.project(S.String)
222
+ // @ts-expect-error encoded type mismatch: original encodes to string, S.Number encodes to number
223
+ client.GetSomething2.project(S.Number)
224
+ const p0 = projected.request(null as any)
225
+
226
+ // struct example: success schema encodes to { a: string | null }
227
+ // good: projection schema also expects { a: string | null } on the encoded side
228
+ const projectedStruct = client.GetStructNullable.project(S.Struct({ a: S.NullOr(S.String) }))
229
+ // bad: { a: S.String } has encoded type { a: string } — does not accept null
230
+ // @ts-expect-error encoded type mismatch: original encodes to { a: string | null }, projection expects { a: string }
231
+ client.GetStructNullable.project(S.Struct({ a: S.String }))
232
+
233
+ const p00 = projected.query(null as any)
234
+ const p = projected.suspense(null as any)
73
235
 
74
236
  expect(true).toBe(true)
75
237
  console.log({
76
238
  a,
77
239
  a0,
78
240
  a00,
79
- c0,
80
241
  b,
81
- c,
82
- d,
83
242
  e,
243
+ de,
244
+ de2,
84
245
  e0,
85
246
  e00,
86
247
  e000,
87
- e0000,
88
248
  e1,
89
249
  e2,
90
250
  f,
91
251
  f0,
252
+ g0,
92
253
  g,
93
- h
254
+ g1,
255
+ g2,
256
+ g3,
257
+ g4,
258
+ g5,
259
+ g6,
260
+ h,
261
+ p0,
262
+ p00,
263
+ p,
264
+ projectedStruct
94
265
  })
95
266
  })
package/test/stubs.ts CHANGED
@@ -4,15 +4,16 @@ import * as Intl from "@formatjs/intl"
4
4
  import { Effect, Layer, ManagedRuntime, Option, S } from "effect-app"
5
5
  import { ApiClientFactory, makeRpcClient } from "effect-app/client"
6
6
  import { RpcContextMap } from "effect-app/rpc"
7
+ import * as Exit from "effect/Exit"
7
8
  import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient"
8
9
  import { ref } from "vue"
9
- import { Commander } from "../src/experimental/commander.js"
10
- import { I18n } from "../src/experimental/intl.js"
11
- import { makeUseCommand } from "../src/experimental/makeUseCommand.js"
12
- import * as Toast from "../src/experimental/toast.js"
13
- import { WithToast } from "../src/experimental/withToast.js"
14
- import { LegacyMutation, makeClient } from "../src/makeClient.js"
10
+ import { Commander } from "../src/commander.js"
11
+ import { I18n } from "../src/intl.js"
12
+ import { makeClient } from "../src/makeClient.js"
15
13
  import { type MakeIntlReturn } from "../src/makeIntl.js"
14
+ import { makeUseCommand } from "../src/makeUseCommand.js"
15
+ import * as Toast from "../src/toast.js"
16
+ import { WithToast } from "../src/withToast.js"
16
17
 
17
18
  const fakeToastLayer = (toasts: any[] = []) =>
18
19
  Layer.effect(
@@ -26,33 +27,34 @@ const fakeToastLayer = (toasts: any[] = []) =>
26
27
  toasts.splice(idx, 1)
27
28
  }
28
29
  }
29
- const fakeToast = (message: string, options?: Toast.ToastOpts) => {
30
- const id = options?.id ?? Math.random().toString(36).substring(2, 15)
31
- console.log(`Toast [${id}]: ${message}`, options)
30
+ const fakeToast =
31
+ (type: "error" | "warning" | "success" | "info") => (message: string, options?: Toast.ToastOpts) => {
32
+ const id = options?.id ?? Math.random().toString(36).substring(2, 15)
33
+ console.log(`Toast [${type}][${id}]: ${message}`, options)
32
34
 
33
- options = { ...options, id }
34
- const idx = toasts.findIndex((_) => _.id === id)
35
- if (idx > -1) {
36
- const toast = toasts[idx]
37
- clearTimeout(toast.timeoutId)
38
- Object.assign(toast, { message, options })
39
- toast.timeoutId = setTimeout(() => {
40
- toasts.splice(idx, 1)
41
- }, options?.timeout ?? 3000)
42
- } else {
43
- const toast: any = { id, message, options }
44
- toast.timeoutId = setTimeout(() => {
45
- toasts.splice(idx, 1)
46
- }, options?.timeout ?? 3000)
47
- toasts.push(toast)
35
+ options = { ...options, id }
36
+ const idx = toasts.findIndex((_) => _.id === id)
37
+ if (idx > -1) {
38
+ const toast = toasts[idx]
39
+ clearTimeout(toast.timeoutId)
40
+ Object.assign(toast, { type, message, options })
41
+ toast.timeoutId = setTimeout(() => {
42
+ toasts.splice(idx, 1)
43
+ }, options?.timeout ?? 3000)
44
+ } else {
45
+ const toast: any = { id, type, message, options }
46
+ toast.timeoutId = setTimeout(() => {
47
+ toasts.splice(idx, 1)
48
+ }, options?.timeout ?? 3000)
49
+ toasts.push(toast)
50
+ }
51
+ return id
48
52
  }
49
- return id
50
- }
51
53
  return Toast.Toast.of(Toast.wrap({
52
- error: fakeToast,
53
- warning: fakeToast,
54
- success: fakeToast,
55
- info: fakeToast,
54
+ error: fakeToast("error"),
55
+ warning: fakeToast("warning"),
56
+ success: fakeToast("success"),
57
+ info: fakeToast("info"),
56
58
  dismiss
57
59
  })) as any
58
60
  })
@@ -92,20 +94,91 @@ export const useExperimental = (
92
94
  }
93
95
 
94
96
  export class RequestContextMap extends RpcContextMap.makeMap({}) {}
95
- export const { TaggedRequest: Req } = makeRpcClient(RequestContextMap)
96
- export class GetSomething2 extends Req<GetSomething2>()("GetSomething2", {
97
+ export const { TaggedRequestFor } = makeRpcClient(RequestContextMap)
98
+
99
+ export const SomethingReq = TaggedRequestFor("Something")
100
+ const SomethingQuery = SomethingReq.Query
101
+ const SomethingCommand = SomethingReq.Command
102
+
103
+ class SomethingGetSomething2 extends SomethingQuery<SomethingGetSomething2>()("GetSomething2", {
97
104
  id: S.String
98
- }, { success: S.NumberFromString }) {}
105
+ }, { success: S.FiniteFromString }) {}
106
+
107
+ class SomethingGetSomething3 extends SomethingQuery<SomethingGetSomething3>()("GetSomething3", {
108
+ id: S.NullOr(S.String).withDefault
109
+ }, { success: S.FiniteFromString }) {}
110
+
111
+ class SomethingGetSomething2WithDependencies
112
+ extends SomethingQuery<SomethingGetSomething2WithDependencies>()("GetSomething2", {
113
+ id: S.String
114
+ }, {
115
+ // this is intentilally fake, to simulate a codec that requires a dependency
116
+ success: S.FiniteFromString as S.Codec<number, string, "dep-a">,
117
+ error: S.String
118
+ })
119
+ {}
120
+
121
+ type SomethingInvalidationResources = {
122
+ GetSomething2: typeof SomethingGetSomething2
123
+ GetSomething2WithDependencies: typeof SomethingGetSomething2WithDependencies
124
+ GetSomething3: typeof SomethingGetSomething3
125
+ }
99
126
 
100
- export class GetSomething2WithDependencies extends Req<GetSomething2WithDependencies>()("GetSomething2", {
127
+ class SomethingDoSomething extends SomethingCommand<
128
+ SomethingDoSomething,
129
+ { Something: SomethingInvalidationResources }
130
+ >()("DoSomething", {
101
131
  id: S.String
102
132
  }, {
103
- // this is intentilally fake, to simulate a codec that requires a dependency
104
- success: S.NumberFromString as S.Codec<number, string, "dep-a">,
105
- error: S.String
133
+ success: S.FiniteFromString
134
+ }, (queryKey, { Something }, input, output) => {
135
+ return [
136
+ { filters: { queryKey } },
137
+ {
138
+ filters: {
139
+ queryKey: [
140
+ Something["GetSomething2"].id,
141
+ input.id,
142
+ Exit.isSuccess(output) ? output.value.toString() : "failed"
143
+ ]
144
+ }
145
+ }
146
+ ]
147
+ }) {}
148
+
149
+ // success schema has encoded shape { a: string | null } — used to test projection constraints
150
+ class SomethingGetStructNullable extends SomethingQuery<SomethingGetStructNullable>()("GetStructNullable", {}, {
151
+ success: S.Struct({ a: S.NullOr(S.String) })
106
152
  }) {}
107
153
 
108
- export const Something = { GetSomething2, GetSomething2WithDependencies, meta: { moduleName: "Something" as const } }
154
+ export const Something = {
155
+ GetSomething2: SomethingGetSomething2,
156
+ GetSomething2WithDependencies: SomethingGetSomething2WithDependencies,
157
+ GetSomething3: SomethingGetSomething3,
158
+ DoSomething: SomethingDoSomething,
159
+ GetStructNullable: SomethingGetStructNullable
160
+ }
161
+
162
+ export const SomethingElseReq = TaggedRequestFor("SomethingElse")
163
+ const SomethingElseQuery = SomethingElseReq.Query
164
+
165
+ class SomethingElseGetSomething2 extends SomethingElseQuery<SomethingElseGetSomething2>()("GetSomething2", {
166
+ id: S.String
167
+ }, { success: S.FiniteFromString }) {}
168
+
169
+ class SomethingElseGetSomething2WithDependencies
170
+ extends SomethingElseQuery<SomethingElseGetSomething2WithDependencies>()("GetSomething2", {
171
+ id: S.String
172
+ }, {
173
+ success: S.FiniteFromString as S.Codec<number, string, "dep-a">,
174
+ error: S.String
175
+ })
176
+ {}
177
+
178
+ export const SomethingElse = {
179
+ GetSomething2: SomethingElseGetSomething2,
180
+ GetSomething2WithDependencies: SomethingElseGetSomething2WithDependencies
181
+ }
109
182
 
110
183
  export const useClient = (
111
184
  options?: { messages?: Record<string, string> | Record<string, MessageFormatElement[]>; toasts: any[] }
@@ -117,8 +190,7 @@ export const useClient = (
117
190
  const api = ApiClientFactory.layer({ url: "bogus", headers: Option.none() }).pipe(
118
191
  Layer.provide(FetchHttpClient.layer)
119
192
  )
120
- const lm = LegacyMutation.Default.pipe(Layer.provide([FakeIntlLayer, FakeToastLayer]))
121
- const layers = Layer.mergeAll(CommanderLayer, WithToastLayer, FakeToastLayer, FakeIntlLayer, api, lm)
193
+ const layers = Layer.mergeAll(CommanderLayer, WithToastLayer, FakeToastLayer, FakeIntlLayer, api)
122
194
 
123
195
  const clientFor_ = ApiClientFactory.makeFor(Layer.empty)
124
196
  return makeClient(() => ManagedRuntime.make(layers), clientFor_, Layer.empty)
package/tsconfig.json CHANGED
@@ -32,7 +32,6 @@
32
32
  "outDir": "build/dist",
33
33
  "resolveJsonModule": true,
34
34
  "moduleResolution": "Node16",
35
- "downlevelIteration": true,
36
35
  "noErrorTruncation": true,
37
36
  "forceConsistentCasingInFileNames": true,
38
37
  "types": [
package/tsconfig.json.bak CHANGED
@@ -8,5 +8,5 @@
8
8
  {
9
9
  "path": "./tsconfig.test.json"
10
10
  }
11
- ],
12
- }
11
+ ]
12
+ }
package/tsconfig.src.json CHANGED
@@ -1,36 +1,36 @@
1
1
  {
2
- "extends": "../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "lib": [
5
- "esnext",
6
- "DOM"
7
- ],
8
- "tsBuildInfoFile": "./dist/.tsbuildinfo",
9
- "esModuleInterop": true,
10
- "rootDir": "./src",
11
- // keep in here, cause madge can't detect it from extended tsconfig
12
- "moduleResolution": "Node16",
13
- "outDir": "./dist"
14
- },
15
- "include": [
16
- "./src/**/*.ts"
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "lib": [
5
+ "esnext",
6
+ "DOM"
17
7
  ],
18
- "exclude": [
19
- "./dist",
20
- "*.test.ts",
21
- "node_modules",
22
- "build",
23
- "lib",
24
- "dist",
25
- "**/*.d.ts.map",
26
- ".git",
27
- ".data",
28
- "**/.*",
29
- "**/*.tmp"
30
- ],
31
- "references": [
32
- {
33
- "path": "../effect-app"
34
- }
35
- ]
36
- }
8
+ "tsBuildInfoFile": "./dist/.tsbuildinfo",
9
+ "esModuleInterop": true,
10
+ "rootDir": "./src",
11
+ // keep in here, cause madge can't detect it from extended tsconfig
12
+ "moduleResolution": "Node16",
13
+ "outDir": "./dist"
14
+ },
15
+ "include": [
16
+ "./src/**/*.ts"
17
+ ],
18
+ "exclude": [
19
+ "./dist",
20
+ "*.test.ts",
21
+ "node_modules",
22
+ "build",
23
+ "lib",
24
+ "dist",
25
+ "**/*.d.ts.map",
26
+ ".git",
27
+ ".data",
28
+ "**/.*",
29
+ "**/*.tmp"
30
+ ],
31
+ "references": [
32
+ {
33
+ "path": "../effect-app"
34
+ }
35
+ ]
36
+ }
@@ -28,6 +28,6 @@
28
28
  "references": [
29
29
  {
30
30
  "path": "./tsconfig.src.json"
31
- },
31
+ }
32
32
  ]
33
- }
33
+ }
package/vitest.config.ts CHANGED
@@ -1,18 +1,18 @@
1
1
  /// <reference types="vitest" />
2
+ import vue from "@vitejs/plugin-vue"
2
3
  import { defineConfig } from "vitest/config"
3
- import vue from '@vitejs/plugin-vue'
4
4
  import makeConfig from "../../vite.config.base"
5
5
 
6
6
  export default defineConfig({
7
7
  ...makeConfig(__dirname),
8
8
  plugins: [vue()],
9
9
  test: {
10
- environment: 'jsdom',
11
- include: ['src/**/*.test.{ts,tsx}', '**/test/**/*.test.{ts,tsx}', '**/__tests__/**/*.test.{ts,tsx}'],
12
- exclude: ['node_modules/**', 'dist/**'],
10
+ environment: "jsdom",
11
+ include: ["src/**/*.test.{ts,tsx}", "**/test/**/*.test.{ts,tsx}", "**/__tests__/**/*.test.{ts,tsx}"],
12
+ exclude: ["node_modules/**", "dist/**"],
13
13
  globals: true
14
14
  },
15
15
  optimizeDeps: {
16
- exclude: ['**/__tests__/**', '**/test/**', '**/*.test.*']
16
+ exclude: ["**/__tests__/**", "**/test/**", "**/*.test.*"]
17
17
  }
18
18
  })