@effect-app/vue 4.0.0-beta.127 → 4.0.0-beta.129

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/makeClient.ts CHANGED
@@ -21,7 +21,7 @@ const mapHandler = <A, E, R, I = void, A2 = A, E2 = E, R2 = R>(
21
21
  map: (self: Effect.Effect<A, E, R>, i: I) => Effect.Effect<A2, E2, R2>
22
22
  ) => Effect.isEffect(handler) ? map(handler, undefined as any) : (i: I) => map(handler(i), i)
23
23
 
24
- export interface RequestExtensions<RT, Id extends string, I, A, E, R> {
24
+ export interface CommandRequestExtensions<RT, Id extends string, I, A, E, R> {
25
25
  /** Defines a Command based on this call, taking the `id` of the call as the `id` of the Command.
26
26
  * The Request function will be taken as the first member of the Command, the Command required input will be the Request input.
27
27
  * see Command.wrap for details */
@@ -39,11 +39,12 @@ export interface RequestExtWithInput<
39
39
  A,
40
40
  E,
41
41
  R
42
- > extends Commander.CommandContextLocal<Id, Id>, RequestExtensions<RT, Id, I, A, E, R> {
42
+ > extends Commander.CommandContextLocal<Id, Id>, CommandRequestExtensions<RT, Id, I, A, E, R> {
43
43
  /**
44
- * Request the endpoint with input
44
+ * Send the request to the endpoint and return the raw Effect response.
45
+ * This does not perform query cache invalidation.
45
46
  */
46
- fetch: (i: I) => Effect.Effect<A, E, R>
47
+ request: (i: I) => Effect.Effect<A, E, R>
47
48
  }
48
49
 
49
50
  export interface RequestExt<
@@ -55,20 +56,57 @@ export interface RequestExt<
55
56
  > extends
56
57
  Commander.CommandContextLocal<Id, Id>,
57
58
  Commander.CommanderWrap<RT, Id, Id, undefined, void, A, E, R>,
58
- RequestExtensions<RT, Id, void, A, E, R>
59
+ CommandRequestExtensions<RT, Id, void, A, E, R>
59
60
  {
60
61
  /**
61
- * Request the endpoint
62
+ * Send the request to the endpoint and return the raw Effect response.
63
+ * This does not perform query cache invalidation.
62
64
  */
63
- fetch: Effect.Effect<A, E, R>
65
+ request: Effect.Effect<A, E, R>
64
66
  }
65
67
 
66
- export type RequestWithExtensions<RT, Req> = Req extends
68
+ export type CommandRequestWithExtensions<RT, Req> = Req extends
67
69
  RequestHandlerWithInput<infer I, infer A, infer E, infer R, infer _Request, infer Id>
68
70
  ? RequestExtWithInput<RT, Id, I, A, E, R>
69
71
  : Req extends RequestHandler<infer A, infer E, infer R, infer _Request, infer Id> ? RequestExt<RT, Id, A, E, R>
70
72
  : never
71
73
 
74
+ export interface QueryExtensionsWithInput<I, A, E, R> {
75
+ /**
76
+ * Send the request to the endpoint and return the raw Effect response.
77
+ * This does not set up query state tracking.
78
+ */
79
+ request: (i: I) => Effect.Effect<A, E, R>
80
+ }
81
+
82
+ export interface QueryExtensions<A, E, R> {
83
+ /**
84
+ * Send the request to the endpoint and return the raw Effect response.
85
+ * This does not set up query state tracking.
86
+ */
87
+ request: Effect.Effect<A, E, R>
88
+ }
89
+
90
+ export type QueryRequestWithExtensions<Req> = Req extends
91
+ RequestHandlerWithInput<infer I, infer A, infer E, infer R, infer _Request, infer _Id>
92
+ ? QueryExtensionsWithInput<I, A, E, R>
93
+ : Req extends RequestHandler<infer A, infer E, infer R, infer _Request, infer _Id> ? QueryExtensions<A, E, R>
94
+ : never
95
+
96
+ type QueryHandler<Req> = Req extends
97
+ RequestHandlerWithInput<infer I, infer A, infer E, infer R, infer Request, infer Id>
98
+ ? Request["type"] extends "query" ? RequestHandlerWithInput<I, A, E, R, Request, Id> : never
99
+ : Req extends RequestHandler<infer A, infer E, infer R, infer Request, infer Id>
100
+ ? Request["type"] extends "query" ? RequestHandler<A, E, R, Request, Id> : never
101
+ : never
102
+
103
+ type CommandHandler<Req> = Req extends
104
+ RequestHandlerWithInput<infer I, infer A, infer E, infer R, infer Request, infer Id>
105
+ ? Request["type"] extends "command" ? RequestHandlerWithInput<I, A, E, R, Request, Id> : never
106
+ : Req extends RequestHandler<infer A, infer E, infer R, infer Request, infer Id>
107
+ ? Request["type"] extends "command" ? RequestHandler<A, E, R, Request, Id> : never
108
+ : never
109
+
72
110
  export interface MutationExtensions<RT, Id extends string, I, A, E, R> {
73
111
  /** Defines a Command based on this mutation, taking the `id` of the mutation as the `id` of the Command.
74
112
  * The Mutation function will be taken as the first member of the Command, the Command required input will be the Mutation input.
@@ -86,17 +124,21 @@ export interface MutationExtWithInput<
86
124
  R
87
125
  > extends MutationExtensions<RT, Id, I, A, E, R> {
88
126
  /**
89
- * Call the endpoint with input
90
- * Invalidate queries based on namespace of this mutation.
91
- * Do not use for queries.
127
+ * Send the request to the endpoint and return the raw Effect response.
128
+ * Also invalidates query caches using the request namespace by default.
129
+ * Namespace invalidation targets parent namespace keys
130
+ * (for example `$project/$configuration.get` invalidates `$project`).
131
+ * Override invalidation in client options via `queryInvalidation`.
92
132
  */
93
133
  (i: I): Effect.Effect<A, E, R>
94
134
  }
95
135
 
96
136
  /**
97
- * Call the endpoint
98
- * Invalidate queries based on namespace of this mutation.
99
- * Do not use for queries.
137
+ * Send the request to the endpoint and return the raw Effect response.
138
+ * Also invalidates query caches using the request namespace by default.
139
+ * Namespace invalidation targets parent namespace keys
140
+ * (for example `$project/$configuration.get` invalidates `$project`).
141
+ * Override invalidation in client options via `queryInvalidation`.
100
142
  */
101
143
  export interface MutationExt<
102
144
  RT,
@@ -121,27 +163,29 @@ declare const useSuspenseQuery_: QueryImpl<any>["useSuspenseQuery"]
121
163
 
122
164
  export interface QueriesWithInput<Request extends Req, Id extends string, I, A, E> {
123
165
  /**
124
- * Effect results are passed to the caller, including errors.
166
+ * Read helper for query requests.
167
+ * Runs as a tracked Vue Query and returns reactive state.
168
+ * Queries read state and should not be used to mutate it.
125
169
  */
126
170
  query: ReturnType<typeof useQuery_<I, E, A, Request, Id>>
127
171
  // TODO or suspense as Option?
128
172
  /**
129
- * The difference with useQuery is that this function will return a Promise you can await in the Setup,
130
- * which ensures that either there always is a latest value, or an error occurs on load.
131
- * So that Suspense and error boundaries can be used.
173
+ * Like `.query`, but returns a Promise for setup-time awaiting.
174
+ * Use this when integrating with Vue Suspense / error boundaries.
132
175
  */
133
176
  suspense: ReturnType<typeof useSuspenseQuery_<I, E, A, Request, Id>>
134
177
  }
135
178
  export interface QueriesWithoutInput<Request extends Req, Id extends string, A, E> {
136
179
  /**
137
- * Effect results are passed to the caller, including errors.
180
+ * Read helper for query requests.
181
+ * Runs as a tracked Vue Query and returns reactive state.
182
+ * Queries read state and should not be used to mutate it.
138
183
  */
139
184
  query: ReturnType<typeof useQuery_<E, A, Request, Id>>
140
185
  // TODO or suspense as Option?
141
186
  /**
142
- * The difference with useQuery is that this function will return a Promise you can await in the Setup,
143
- * which ensures that either there always is a latest value, or an error occurs on load.
144
- * So that Suspense and error boundaries can be used.
187
+ * Like `.query`, but returns a Promise for setup-time awaiting.
188
+ * Use this when integrating with Vue Suspense / error boundaries.
145
189
  */
146
190
  suspense: ReturnType<typeof useSuspenseQuery_<E, A, Request, Id>>
147
191
  }
@@ -153,14 +197,16 @@ export type MissingDependencies<RT, R> = {
153
197
 
154
198
  export type Queries<RT, Req> = Req extends
155
199
  RequestHandlerWithInput<infer I, infer A, infer E, infer R, infer Request, infer Id>
156
- ? Exclude<R, RT> extends never ? QueriesWithInput<Request, Id, I, A, E>
157
- : {
158
- query: MissingDependencies<RT, R> & {}
159
- suspense: MissingDependencies<RT, R> & {}
160
- }
200
+ ? Request["type"] extends "query" ? Exclude<R, RT> extends never ? QueriesWithInput<Request, Id, I, A, E>
201
+ : {
202
+ query: MissingDependencies<RT, R> & {}
203
+ suspense: MissingDependencies<RT, R> & {}
204
+ }
205
+ : never
161
206
  : Req extends RequestHandler<infer A, infer E, infer R, infer Request, infer Id>
162
- ? Exclude<R, RT> extends never ? QueriesWithoutInput<Request, Id, A, E>
163
- : { query: MissingDependencies<RT, R> & {}; suspense: MissingDependencies<RT, R> & {} }
207
+ ? Request["type"] extends "query" ? Exclude<R, RT> extends never ? QueriesWithoutInput<Request, Id, A, E>
208
+ : { query: MissingDependencies<RT, R> & {}; suspense: MissingDependencies<RT, R> & {} }
209
+ : never
164
210
  : never
165
211
 
166
212
  const _useMutation = makeMutation()
@@ -377,6 +423,9 @@ export const makeClient = <RT_, RTHooks>(
377
423
  ) => {
378
424
  const queries = Struct.keys(client).reduce(
379
425
  (acc, key) => {
426
+ if (client[key].Request.type !== "query") {
427
+ return acc
428
+ }
380
429
  ;(acc as any)[camelCase(key) + "Query"] = Object.assign(useQuery(client[key] as any), {
381
430
  id: client[key].id
382
431
  })
@@ -388,14 +437,20 @@ export const makeClient = <RT_, RTHooks>(
388
437
  {} as
389
438
  & {
390
439
  // apparently can't get JSDoc in here..
391
- [Key in keyof typeof client as `${ToCamel<string & Key>}Query`]: Queries<RT, typeof client[Key]>["query"]
440
+ [
441
+ Key in keyof typeof client as QueryHandler<typeof client[Key]> extends never ? never
442
+ : `${ToCamel<string & Key>}Query`
443
+ ]: Queries<RT, QueryHandler<typeof client[Key]>>["query"]
392
444
  }
393
445
  // todo: or suspense as an Option?
394
446
  & {
395
447
  // apparently can't get JSDoc in here..
396
- [Key in keyof typeof client as `${ToCamel<string & Key>}SuspenseQuery`]: Queries<
448
+ [
449
+ Key in keyof typeof client as QueryHandler<typeof client[Key]> extends never ? never
450
+ : `${ToCamel<string & Key>}SuspenseQuery`
451
+ ]: Queries<
397
452
  RT,
398
- typeof client[Key]
453
+ QueryHandler<typeof client[Key]>
399
454
  >["suspense"]
400
455
  }
401
456
  )
@@ -408,6 +463,9 @@ export const makeClient = <RT_, RTHooks>(
408
463
  const Command = useCommand()
409
464
  const mutations = Struct.keys(client).reduce(
410
465
  (acc, key) => {
466
+ if (client[key].Request.type !== "command") {
467
+ return acc
468
+ }
411
469
  const mut = client[key].handler
412
470
  const fn = Command.fn(client[key].id)
413
471
  const wrap = Command.wrap({ mutate: Effect.isEffect(mut) ? () => mut : mut, id: client[key].id })
@@ -419,9 +477,12 @@ export const makeClient = <RT_, RTHooks>(
419
477
  return acc
420
478
  },
421
479
  {} as {
422
- [Key in keyof typeof client as `${ToCamel<string & Key>}Request`]: RequestWithExtensions<
480
+ [
481
+ Key in keyof typeof client as CommandHandler<typeof client[Key]> extends never ? never
482
+ : `${ToCamel<string & Key>}Request`
483
+ ]: CommandRequestWithExtensions<
423
484
  RT | RTHooks,
424
- typeof client[Key]
485
+ CommandHandler<typeof client[Key]>
425
486
  >
426
487
  }
427
488
  )
@@ -435,15 +496,21 @@ export const makeClient = <RT_, RTHooks>(
435
496
  const mutation = useMutation()
436
497
  const mutations = Struct.keys(client).reduce(
437
498
  (acc, key) => {
499
+ if (client[key].Request.type !== "command") {
500
+ return acc
501
+ }
438
502
  const mut: any = mutation(client[key] as any)
439
503
  const wrap = Command.wrap({ mutate: Effect.isEffect(mut) ? () => mut : mut, id: client[key].id })
440
504
  ;(acc as any)[camelCase(key) + "Mutation"] = Object.assign(mut, { wrap })
441
505
  return acc
442
506
  },
443
507
  {} as {
444
- [Key in keyof typeof client as `${ToCamel<string & Key>}Mutation`]: MutationWithExtensions<
508
+ [
509
+ Key in keyof typeof client as CommandHandler<typeof client[Key]> extends never ? never
510
+ : `${ToCamel<string & Key>}Mutation`
511
+ ]: MutationWithExtensions<
445
512
  RT | RTHooks,
446
- typeof client[Key]
513
+ CommandHandler<typeof client[Key]>
447
514
  >
448
515
  }
449
516
  )
@@ -463,50 +530,59 @@ export const makeClient = <RT_, RTHooks>(
463
530
  const invalidation = queryInvalidation?.(client)
464
531
  const extended = Struct.keys(client).reduce(
465
532
  (acc, key) => {
533
+ const requestType = client[key].Request.type
466
534
  const fn = Command.fn(client[key].id)
467
- const mutate = extendM(
468
- mutation(
469
- client[key] as any,
470
- invalidation?.[key] ? { queryInvalidation: invalidation[key] } : undefined
471
- ),
472
- (mutate) =>
473
- Object.assign(
474
- mutate,
475
- {
476
- wrap: Command.wrap({ mutate: Effect.isEffect(mutate) ? () => mutate : mutate, id: client[key].id })
477
- }
478
- )
479
- )
480
-
481
535
  const h_ = client[key].handler
482
536
  const wrapInput = Effect.isEffect(h_)
483
537
  ? () => h_
484
538
  : (...args: [any]) => h_(...args)
485
- const fetch = Effect.isEffect(h_) ? h_ : wrapInput
539
+ const request = Effect.isEffect(h_) ? h_ : wrapInput
486
540
  ;(acc as any)[key] = Object.assign(
487
- {},
488
- client[key],
489
- fn, // to get the i18n key etc.
490
- {
491
- fetch,
492
- mutate,
493
- query: useQuery(client[key] as any),
494
- suspense: useSuspenseQuery(client[key] as any),
495
- wrap: Command.wrap({ mutate: wrapInput, id: client[key].id }),
496
- fn
497
- }
541
+ requestType === "query"
542
+ ? {
543
+ ...client[key],
544
+ request,
545
+ query: useQuery(client[key] as any),
546
+ suspense: useSuspenseQuery(client[key] as any)
547
+ }
548
+ : {
549
+ mutate: extendM(
550
+ mutation(
551
+ client[key] as any,
552
+ invalidation?.[key] ? { queryInvalidation: invalidation[key] } : undefined
553
+ ),
554
+ (mutate) =>
555
+ Object.assign(
556
+ mutate,
557
+ {
558
+ wrap: Command.wrap({
559
+ mutate: Effect.isEffect(mutate) ? () => mutate : mutate,
560
+ id: client[key].id
561
+ })
562
+ }
563
+ )
564
+ ),
565
+ ...client[key],
566
+ ...fn, // to get the i18n key etc.
567
+ request,
568
+ fn,
569
+ wrap: Command.wrap({ mutate: wrapInput, id: client[key].id })
570
+ }
498
571
  )
499
572
  return acc
500
573
  },
501
574
  {} as {
502
575
  [Key in keyof typeof client]:
503
576
  & typeof client[Key]
504
- & RequestWithExtensions<RT | RTHooks, typeof client[Key]>
505
- & {
506
- mutate: MutationWithExtensions<RT | RTHooks, typeof client[Key]>
507
- Input: typeof client[Key] extends RequestHandlerWithInput<infer I, any, any, any, any, any> ? I : never
508
- }
509
- & Queries<RT, typeof client[Key]>
577
+ & (QueryHandler<typeof client[Key]> extends never ? {}
578
+ :
579
+ & QueryRequestWithExtensions<QueryHandler<typeof client[Key]>>
580
+ & Queries<RT, QueryHandler<typeof client[Key]>>)
581
+ & (CommandHandler<typeof client[Key]> extends never ? {}
582
+ : CommandRequestWithExtensions<RT | RTHooks, CommandHandler<typeof client[Key]>>)
583
+ & (CommandHandler<typeof client[Key]> extends never ? {}
584
+ : { mutate: MutationWithExtensions<RT | RTHooks, CommandHandler<typeof client[Key]>> })
585
+ & { Input: typeof client[Key] extends RequestHandlerWithInput<infer I, any, any, any, any, any> ? I : never }
510
586
  }
511
587
  )
512
588
  return Object.assign(extended, { helpers: { ...mapRequest(client), ...mapMutation(client), ...mapQuery(client) } })
package/src/query.ts CHANGED
@@ -127,13 +127,13 @@ export const makeQuery = <R>(getRuntime: () => Context.Context<R>) => {
127
127
  const runPromise = makeRunPromise(getRuntime())
128
128
  const arr = arg
129
129
  const req: { value: I } = !arg
130
- ? undefined
130
+ ? undefined as any
131
131
  : typeof arr === "function"
132
132
  ? ({
133
133
  get value() {
134
134
  return (arr as any)()
135
135
  }
136
- } as any)
136
+ })
137
137
  : ref(arg)
138
138
  const queryKey = makeQueryKey(q)
139
139
  const handler = q.handler