@effect-app/vue 2.94.0 → 4.0.0-beta.0

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 (62) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/errorReporter.d.ts +2 -2
  3. package/dist/errorReporter.d.ts.map +1 -1
  4. package/dist/errorReporter.js +9 -9
  5. package/dist/experimental/commander.d.ts +46 -66
  6. package/dist/experimental/commander.d.ts.map +1 -1
  7. package/dist/experimental/commander.js +27 -29
  8. package/dist/experimental/confirm.d.ts +11 -5
  9. package/dist/experimental/confirm.d.ts.map +1 -1
  10. package/dist/experimental/confirm.js +19 -6
  11. package/dist/experimental/intl.d.ts +2 -21
  12. package/dist/experimental/intl.d.ts.map +1 -1
  13. package/dist/experimental/intl.js +4 -4
  14. package/dist/experimental/makeUseCommand.js +2 -2
  15. package/dist/experimental/toast.d.ts +3 -35
  16. package/dist/experimental/toast.d.ts.map +1 -1
  17. package/dist/experimental/toast.js +19 -5
  18. package/dist/experimental/withToast.d.ts +6 -4
  19. package/dist/experimental/withToast.d.ts.map +1 -1
  20. package/dist/experimental/withToast.js +10 -8
  21. package/dist/form.d.ts +2 -2
  22. package/dist/form.d.ts.map +1 -1
  23. package/dist/form.js +47 -47
  24. package/dist/lib.d.ts.map +1 -1
  25. package/dist/lib.js +11 -9
  26. package/dist/makeClient.d.ts +24 -21
  27. package/dist/makeClient.d.ts.map +1 -1
  28. package/dist/makeClient.js +28 -29
  29. package/dist/mutate.d.ts.map +1 -1
  30. package/dist/mutate.js +7 -7
  31. package/dist/query.d.ts +6 -4
  32. package/dist/query.d.ts.map +1 -1
  33. package/dist/query.js +26 -17
  34. package/dist/routeParams.d.ts +2 -4
  35. package/dist/routeParams.d.ts.map +1 -1
  36. package/dist/routeParams.js +3 -15
  37. package/dist/runtime.d.ts +1 -1
  38. package/dist/runtime.d.ts.map +1 -1
  39. package/dist/runtime.js +4 -4
  40. package/package.json +20 -20
  41. package/src/errorReporter.ts +11 -11
  42. package/src/experimental/commander.ts +81 -84
  43. package/src/experimental/confirm.ts +21 -6
  44. package/src/experimental/intl.ts +3 -3
  45. package/src/experimental/makeUseCommand.ts +1 -1
  46. package/src/experimental/toast.ts +23 -4
  47. package/src/experimental/withToast.ts +10 -7
  48. package/src/form.ts +56 -64
  49. package/src/lib.ts +10 -8
  50. package/src/makeClient.ts +61 -54
  51. package/src/mutate.ts +6 -7
  52. package/src/query.ts +28 -21
  53. package/src/routeParams.ts +9 -23
  54. package/src/runtime.ts +6 -6
  55. package/test/Mutation.test.ts +41 -42
  56. package/test/dist/form.test.d.ts.map +1 -1
  57. package/test/dist/stubs.d.ts +111 -53
  58. package/test/dist/stubs.d.ts.map +1 -1
  59. package/test/dist/stubs.js +8 -8
  60. package/test/form.test.ts +7 -6
  61. package/test/stubs.ts +43 -41
  62. package/tsconfig.json +1 -27
package/src/form.ts CHANGED
@@ -1,8 +1,6 @@
1
1
  import { createIntl, type IntlFormatters } from "@formatjs/intl"
2
- import * as JSONSchema from "effect/JSONSchema"
3
- import type { ParseError } from "effect/ParseResult"
4
2
  import type {} from "intl-messageformat"
5
- import { Either, Option, pipe, S } from "effect-app"
3
+ import { Cause, Exit, Option, pipe, S } from "effect-app"
6
4
  import type { Schema } from "effect-app/Schema"
7
5
  import type { Unbranded } from "effect-app/Schema/brand"
8
6
  import type { IsUnion } from "effect-app/utils"
@@ -11,23 +9,18 @@ import { capitalize, ref } from "vue"
11
9
  // type GetSchemaFromProp<T> = T extends Field<infer S, any, any, any> ? S
12
10
  // : never
13
11
 
14
- function getTypeLiteralAST(ast: S.AST.AST): S.AST.TypeLiteral | null {
15
- switch (ast._tag) {
16
- case "TypeLiteral": {
17
- return ast
18
- }
19
- case "Transformation": {
20
- // this may be not correct for transformations from a type literal to something
21
- // that is not a type literal nor a class because we would prefer the from AST
22
- return getTypeLiteralAST(ast.to) ?? getTypeLiteralAST(ast.from)
23
- }
24
- case "Refinement": {
25
- return getTypeLiteralAST(ast.from)
26
- }
27
- default: {
28
- return null
12
+ function getObjectsAST(ast: S.AST.AST): S.AST.Objects | null {
13
+ if (S.AST.isObjects(ast)) {
14
+ return ast
15
+ }
16
+ if (S.AST.isDeclaration(ast)) {
17
+ for (const typeParam of ast.typeParameters) {
18
+ const result = getObjectsAST(typeParam)
19
+ if (result) return result
29
20
  }
21
+ return null
30
22
  }
23
+ return null
31
24
  }
32
25
 
33
26
  export function convertIn(v: string | null, type?: "text" | "float" | "int") {
@@ -114,29 +107,26 @@ function handlePropertySignature(
114
107
  {
115
108
  const schema = S.make(propertySignature.type)
116
109
 
117
- switch (schema.ast._tag) {
118
- case "Transformation": {
119
- const tl = getTypeLiteralAST(schema.ast)
120
-
121
- return tl
122
- ? handlePropertySignature(
123
- new S.AST.PropertySignature(
124
- propertySignature.name,
125
- tl,
126
- propertySignature.isOptional,
127
- propertySignature.isReadonly,
128
- propertySignature.annotations
129
- )
110
+ if (S.AST.isDeclaration(schema.ast)) {
111
+ const tl = getObjectsAST(schema.ast)
112
+ return tl
113
+ ? handlePropertySignature(
114
+ new S.AST.PropertySignature(
115
+ propertySignature.name,
116
+ tl
130
117
  )
131
- : buildFieldInfo(propertySignature)
132
- }
133
- case "TypeLiteral": {
118
+ )
119
+ : buildFieldInfo(propertySignature)
120
+ }
121
+
122
+ switch (schema.ast._tag) {
123
+ case "Objects": {
134
124
  return buildFieldInfoFromFieldsRoot(
135
- schema as S.Schema<Record<PropertyKey, any>, Record<PropertyKey, any>, never>
125
+ schema as S.Schema<Record<PropertyKey, any>>
136
126
  )
137
127
  }
138
128
  case "Union": {
139
- const allTypeLiterals = schema.ast.types.every(getTypeLiteralAST)
129
+ const allTypeLiterals = schema.ast.types.every(getObjectsAST)
140
130
 
141
131
  if (allTypeLiterals) {
142
132
  const members = schema
@@ -146,15 +136,12 @@ function handlePropertySignature(
146
136
  // syntehtic property signature as if each union member were the only member
147
137
  new S.AST.PropertySignature(
148
138
  propertySignature.name,
149
- elAst,
150
- propertySignature.isOptional,
151
- propertySignature.isReadonly,
152
- propertySignature.annotations
139
+ elAst
153
140
  )
154
141
  )
155
142
  .flatMap((ps) => {
156
143
  // try to retrieve the _tag literal to set _infoTag later
157
- const typeLiteral = getTypeLiteralAST(ps.type)
144
+ const typeLiteral = getObjectsAST(ps.type)
158
145
 
159
146
  const tagPropertySignature = typeLiteral?.propertySignatures.find((_) => _.name === "_tag")
160
147
  const tagLiteral = tagPropertySignature
@@ -207,7 +194,7 @@ export function buildFieldInfoFromFields<
207
194
  From extends Record<PropertyKey, any>,
208
195
  To extends Record<PropertyKey, any>
209
196
  >(
210
- schema: Schema<To, From, never> & { fields?: S.Struct.Fields }
197
+ schema: (Schema<To> | S.Codec<To, From>) & { fields?: S.Struct.Fields }
211
198
  ) {
212
199
  return buildFieldInfoFromFieldsRoot(schema).fields
213
200
  }
@@ -217,9 +204,9 @@ export function buildFieldInfoFromFieldsRoot<
217
204
  To extends Record<PropertyKey, any>,
218
205
  R
219
206
  >(
220
- schema: Schema<To, From, R> & { fields?: S.Struct.Fields }
207
+ schema: (Schema<To> | S.Codec<To, From, R>) & { fields?: S.Struct.Fields }
221
208
  ): NestedFieldInfo<To> {
222
- const ast = getTypeLiteralAST(schema.ast)
209
+ const ast = getObjectsAST(schema.ast)
223
210
 
224
211
  if (!ast) throw new Error("not a struct type")
225
212
  return ast.propertySignatures.reduce(
@@ -258,25 +245,25 @@ function buildFieldInfo(
258
245
  property: S.AST.PropertySignature
259
246
  ): FieldInfo<any> {
260
247
  const propertyKey = property.name
261
- const schema = S.make<unknown, unknown, never>(property.type)
262
- const metadata = getMetadataFromSchema(property.type) // TODO
263
- const parse = S.decodeUnknownEither(schema)
248
+ const schema = S.make<S.Schema<unknown>>(property.type)
249
+ const metadata = getMetadataFromSchema(property.type)
250
+ const parse = S.decodeUnknownExit(schema as S.Schema<unknown> & { readonly DecodingServices: never })
264
251
 
265
252
  const nullableOrUndefined = S.AST.isUnion(property.type)
266
- && (property.type.types.includes(S.Null.ast) || property.type.types.some((_) => _._tag === "UndefinedKeyword"))
253
+ && (property.type.types.includes(S.Null.ast) || property.type.types.some((_) => _._tag === "Undefined"))
267
254
  const realSelf = nullableOrUndefined && S.AST.isUnion(property.type)
268
- ? property.type.types.filter((_) => _ !== S.Null.ast && _._tag !== "UndefinedKeyword")[0]!
255
+ ? property.type.types.filter((_) => _ !== S.Null.ast && _._tag !== "Undefined")[0]!
269
256
  : property.type
270
- const id = S.AST.getIdentifierAnnotation(property.type)
271
- const id2 = S.AST.getIdentifierAnnotation(realSelf)
257
+ const id = S.AST.resolveIdentifier(property.type)
258
+ const id2 = S.AST.resolveIdentifier(realSelf)
272
259
 
273
- function renderError(e: ParseError, v: unknown) {
260
+ function renderError(e: S.SchemaError, v: unknown) {
274
261
  const err = e.toString()
275
262
 
276
263
  const custom = customSchemaErrors.value.get(property.type)
277
264
  ?? customSchemaErrors.value.get(realSelf)
278
- ?? (Option.isSome(id) ? customSchemaErrors.value.get(id.value) : undefined)
279
- ?? (Option.isSome(id2) ? customSchemaErrors.value.get(id2.value) : undefined)
265
+ ?? (id ? customSchemaErrors.value.get(id) : undefined)
266
+ ?? (id2 ? customSchemaErrors.value.get(id2) : undefined)
280
267
 
281
268
  if (custom) {
282
269
  return custom(err, e, v)
@@ -366,9 +353,12 @@ function buildFieldInfo(
366
353
  const parseRule = (v: unknown) =>
367
354
  pipe(
368
355
  parse(v),
369
- Either.match({
370
- onLeft: (_) => renderError(_, v),
371
- onRight: () => true
356
+ Exit.match({
357
+ onFailure: (cause) => {
358
+ const err = Cause.findErrorOption(cause)
359
+ return Option.isSome(err) ? renderError(err.value, v) : "Unknown error"
360
+ },
361
+ onSuccess: () => true
372
362
  })
373
363
  )
374
364
 
@@ -429,14 +419,16 @@ export function getMetadataFromSchema(
429
419
 
430
420
  let jschema: any
431
421
  try {
432
- jschema = JSONSchema.make(S.make(realSelf)) as any
433
- } catch (err) {
422
+ const doc = S.toJsonSchemaDocument(S.make<S.Schema<unknown>>(realSelf))
423
+ jschema = doc.schema as any
424
+ const defs = doc.definitions as Record<string, any>
425
+ // resolve $ref against definitions
426
+ while (jschema["$ref"] && jschema["$ref"].startsWith("#/$defs/")) {
427
+ const { $ref: _, ...rest } = jschema
428
+ jschema = { ...defs[jschema["$ref"].replace("#/$defs/", "")], ...rest }
429
+ }
430
+ } catch (_err) {
434
431
  jschema = {}
435
- // console.warn("error getting jsonschema from ", err, ast)
436
- }
437
- while (jschema["$ref"] && jschema["$ref"].startsWith("#/$defs/")) {
438
- const { $ref: _, ...rest } = jschema
439
- jschema = { ...jschema["$defs"][jschema["$ref"].replace("#/$defs/", "")], ...rest }
440
432
  }
441
433
  // or we need to add these info directly in the refinement like the minimum
442
434
  // or find a jsonschema parser whojoins all of them
package/src/lib.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { isHttpClientError } from "@effect/platform/HttpClientError"
2
1
  import { type Pausable, useIntervalFn, type UseIntervalFnOptions } from "@vueuse/core"
3
- import { Cause, type Effect, LogLevel, pipe } from "effect-app"
2
+ import { Cause, type Effect, pipe } from "effect-app"
4
3
  import { type Req } from "effect-app/client"
5
4
  import type { ClientForOptions, RequestHandler, RequestHandlerWithInput } from "effect-app/client/clientFor"
5
+ import { isHttpClientError } from "effect/unstable/http/HttpClientError"
6
6
  import type { MaybeRefOrGetter } from "vue"
7
7
  import { reportError } from "./errorReporter.js"
8
8
 
@@ -17,12 +17,14 @@ const determineLevel = (cause: Cause.Cause<unknown>) => {
17
17
  if (!isHttpClientError(sq)) {
18
18
  return undefined
19
19
  }
20
- const causeStr = sq.cause?.toString().toLowerCase()
21
- switch (sq._tag) {
22
- case "RequestError":
23
- return sq.reason === "Transport" ? LogLevel.Info : undefined
24
- case "ResponseError":
25
- return sq.reason === "Decode" && filters.some((_) => causeStr?.includes(_)) ? LogLevel.Info : undefined
20
+ const causeStr = sq.reason.message?.toLowerCase()
21
+ switch (sq.reason._tag) {
22
+ case "TransportError":
23
+ return "Info" as const
24
+ case "DecodeError":
25
+ return filters.some((_) => causeStr?.includes(_)) ? "Info" as const : undefined
26
+ default:
27
+ return undefined
26
28
  }
27
29
  }
28
30
 
package/src/makeClient.ts CHANGED
@@ -2,15 +2,14 @@
2
2
  import * as Result from "@effect-atom/atom/Result"
3
3
  import { type InvalidateOptions, type InvalidateQueryFilters, isCancelledError, type QueryObserverResult, type RefetchOptions, type UseQueryReturnType } from "@tanstack/vue-query"
4
4
  import { camelCase } from "change-case"
5
- import { Cause, Effect, Exit, type Layer, type ManagedRuntime, Match, Option, Runtime, S, Struct } from "effect-app"
5
+ import { Cause, Data, Effect, Exit, Layer, type ManagedRuntime, Match, Option, S, ServiceMap, Struct } from "effect-app"
6
6
  import { type ApiClientFactory, type Req } from "effect-app/client"
7
7
  import type { RequestHandler, RequestHandlers, RequestHandlerWithInput, Requests } from "effect-app/client/clientFor"
8
8
  import { ErrorSilenced, type SupportedErrors } from "effect-app/client/errors"
9
9
  import { constant, identity, pipe, tuple } from "effect-app/Function"
10
10
  import { type OperationFailure, OperationSuccess } from "effect-app/Operations"
11
- import { type Schema } from "effect-app/Schema"
12
11
  import { dropUndefinedT, extendM } from "effect-app/utils"
13
- import { type RuntimeFiber } from "effect/Fiber"
12
+ import { type Fiber } from "effect/Fiber"
14
13
  import { computed, type ComputedRef, onBeforeUnmount, type Ref, ref, watch, type WatchSource } from "vue"
15
14
  import { reportMessage } from "./errorReporter.js"
16
15
  import { type Commander, CommanderStatic } from "./experimental/commander.js"
@@ -20,7 +19,7 @@ import { Toast } from "./experimental/toast.js"
20
19
  import { buildFieldInfoFromFieldsRoot } from "./form.js"
21
20
  import { reportRuntimeError } from "./lib.js"
22
21
  import { asResult, makeMutation, type MutationOptions, type MutationOptionsBase, mutationResultToVue, type Res, useMakeMutation } from "./mutate.js"
23
- import { type CustomUndefinedInitialQueryOptions, type KnownFiberFailure, makeQuery } from "./query.js"
22
+ import { type CustomUndefinedInitialQueryOptions, makeQuery } from "./query.js"
24
23
 
25
24
  const mapHandler = <A, E, R, I = void, A2 = A, E2 = E, R2 = R>(
26
25
  handler: Effect.Effect<A, E, R> | ((i: I) => Effect.Effect<A, E, R>),
@@ -180,12 +179,11 @@ export type Queries<RT, Req> = Req extends
180
179
  /**
181
180
  * Use this after handling an error yourself, still continueing on the Error track, but the error will not be reported.
182
181
  */
183
- export class SuppressErrors extends Cause.YieldableError {
184
- readonly _tag = "SuppressErrors"
185
- readonly [ErrorSilenced] = true
182
+ export class SuppressErrors extends Data.TaggedError("SuppressErrors")<{}> {
183
+ readonly [ErrorSilenced] = true as const
186
184
  }
187
185
 
188
- export type ResponseErrors = S.ParseResult.ParseError | SupportedErrors | SuppressErrors | OperationFailure
186
+ export type ResponseErrors = S.SchemaError | SupportedErrors | SuppressErrors | OperationFailure
189
187
 
190
188
  export interface Opts<
191
189
  A,
@@ -290,16 +288,16 @@ function handleRequest<
290
288
  const handleEffect = (i: any) => (self: Effect.Effect<Exit.Exit<A, E>, never, R>) =>
291
289
  self.pipe(
292
290
  Effect.tap(
293
- Exit.matchEffect({
291
+ Effect.matchCauseEffect({
294
292
  onSuccess: (r) => options.onSuccess(r, i),
295
293
  onFailure: (cause) =>
296
294
  Effect.gen(function*() {
297
- if (Cause.isInterruptedOnly(cause)) {
295
+ if (Cause.hasInterruptsOnly(cause)) {
298
296
  console.info(`Interrupted while trying to ${action}`)
299
297
  return
300
298
  }
301
299
 
302
- const fail = Cause.failureOption(cause)
300
+ const fail = Cause.findErrorOption(cause)
303
301
  if (Option.isSome(fail)) {
304
302
  if (fail.value._tag === "SuppressErrors") {
305
303
  console.info(`Suppressed error trying to ${action}`, fail.value)
@@ -321,7 +319,7 @@ function handleRequest<
321
319
  })
322
320
  })
323
321
  ),
324
- Effect.withSpan(`mutation ${id}`, { captureStackTrace: false })
322
+ Effect.withSpan(`mutation ${id}`, {}, { captureStackTrace: false })
325
323
  )
326
324
  return Object.assign(
327
325
  Effect.isEffect(f)
@@ -359,7 +357,7 @@ export const useMutation: typeof _useMutation = <
359
357
  Object.assign(
360
358
  mapHandler(
361
359
  _useMutation(self as any, options),
362
- Effect.withSpan(`mutation ${self.id}`, { captureStackTrace: false })
360
+ Effect.withSpan(`mutation ${self.id}`, {}, { captureStackTrace: false })
363
361
  ) as any,
364
362
  { id: self.id }
365
363
  )
@@ -385,7 +383,7 @@ export const useMutationInt = (): typeof _useMutation => {
385
383
  Object.assign(
386
384
  mapHandler(
387
385
  _useMutation(self as any, options),
388
- Effect.withSpan(`mutation ${self.id}`, { captureStackTrace: false })
386
+ Effect.withSpan(`mutation ${self.id}`, {}, { captureStackTrace: false })
389
387
  ) as any,
390
388
  { id: self.id }
391
389
  )
@@ -393,7 +391,7 @@ export const useMutationInt = (): typeof _useMutation => {
393
391
 
394
392
  export class LegacyMutationImpl<RT> {
395
393
  constructor(
396
- private readonly getRuntime: () => Runtime.Runtime<RT>,
394
+ private readonly getRuntime: () => ServiceMap.ServiceMap<RT>,
397
395
  private readonly toast: Toast,
398
396
  private readonly intl: I18n
399
397
  ) {}
@@ -437,12 +435,17 @@ export class LegacyMutationImpl<RT> {
437
435
  type MH = NonNullable<NonNullable<typeof options>["mapHandler"]>
438
436
  const mh = options?.mapHandler ?? identity as MH
439
437
 
440
- const [a, b] = asResult(mapHandler(mapHandler(unsafe as any, mh), Effect.tapDefect(reportRuntimeError)) as any)
438
+ const [a, b] = asResult(
439
+ mapHandler(
440
+ mapHandler(unsafe as any, mh),
441
+ Effect.tapCauseIf(Cause.hasDies, (cause) => reportRuntimeError(cause))
442
+ ) as any
443
+ )
441
444
  return [
442
445
  a,
443
446
  mapHandler(
444
447
  b,
445
- Effect.withSpan(`mutation ${self.id}`, { captureStackTrace: false })
448
+ Effect.withSpan(`mutation ${self.id}`, {}, { captureStackTrace: false })
446
449
  )
447
450
  ] as const as any
448
451
  }
@@ -537,7 +540,7 @@ export class LegacyMutationImpl<RT> {
537
540
  }
538
541
 
539
542
  function renderError(e: ResponseErrors): string {
540
- return Match.value(e).pipe(
543
+ return Match.value(e as any).pipe(
541
544
  Match.tags({
542
545
  // HttpErrorRequest: e =>
543
546
  // this.intl.value.formatMessage(
@@ -573,12 +576,12 @@ export class LegacyMutationImpl<RT> {
573
576
  // { id: "handle.response_error" },
574
577
  // { error: `${e.error}` },
575
578
  // ),
576
- ParseError: (e) => {
579
+ SchemaError: (e: any) => {
577
580
  console.warn(e.toString())
578
581
  return self.intl.formatMessage({ id: "validation.failed" })
579
582
  }
580
583
  }),
581
- Match.orElse((e) => `${e.message ?? e._tag ?? e}`)
584
+ Match.orElse((e: any) => `${e.message ?? e._tag ?? e}`)
582
585
  )
583
586
  }
584
587
  }
@@ -652,12 +655,12 @@ export class LegacyMutationImpl<RT> {
652
655
  handler: Effect.isEffect(handler)
653
656
  ? (pipe(
654
657
  Effect.annotateCurrentSpan({ action }),
655
- Effect.zipRight(handler)
658
+ Effect.andThen(handler)
656
659
  ) as any)
657
660
  : (...args: [any]) =>
658
661
  pipe(
659
662
  Effect.annotateCurrentSpan({ action }),
660
- Effect.zipRight(handler(...args))
663
+ Effect.andThen(handler(...args))
661
664
  )
662
665
  }, options ? dropUndefinedT(options) : undefined)
663
666
 
@@ -939,7 +942,12 @@ export class LegacyMutationImpl<RT> {
939
942
  type MH = NonNullable<NonNullable<typeof options>["mapHandler"]>
940
943
  const mh = options?.mapHandler ?? identity as MH
941
944
 
942
- const [a, b] = asResult(mapHandler(mapHandler(unsafe as any, mh), Effect.tapDefect(reportRuntimeError)) as any)
945
+ const [a, b] = asResult(
946
+ mapHandler(
947
+ mapHandler(unsafe as any, mh),
948
+ Effect.tapCauseIf(Cause.hasDies, (cause) => reportRuntimeError(cause))
949
+ ) as any
950
+ )
943
951
 
944
952
  return tuple(
945
953
  computed(() => mutationResultToVue(a.value)),
@@ -1002,36 +1010,34 @@ export class LegacyMutationImpl<RT> {
1002
1010
  OnSubmitA
1003
1011
  >(
1004
1012
  s:
1005
- & Schema<
1006
- To,
1007
- From,
1008
- RT
1009
- >
1013
+ & S.Schema<To>
1010
1014
  & { new(c: C): any; extend: any; fields: S.Struct.Fields },
1011
1015
  state: Ref<Omit<From, "_tag">>,
1012
1016
  onSubmit: (a: To) => Effect.Effect<OnSubmitA, never, RT>
1013
1017
  ) => {
1014
1018
  const fields = buildFieldInfoFromFieldsRoot(s).fields
1015
- const schema = S.Struct(Struct.omit(s.fields, "_tag")) as any
1016
- const parse = S.decodeUnknown<any, any, RT>(schema)
1019
+ const schema = S.Struct(Struct.omit(s.fields, ["_tag"])) as unknown as S.Schema<any> & {
1020
+ readonly DecodingServices: never
1021
+ }
1022
+ const parse = S.decodeUnknownSync(schema)
1017
1023
  const isDirty = ref(false)
1018
1024
  const isValid = ref(true)
1019
1025
  const isLoading = ref(false)
1020
- const runPromise = Runtime.runPromise(this.getRuntime())
1026
+ const runPromise = Effect.runPromiseWith(this.getRuntime())
1021
1027
 
1022
1028
  const submit1 =
1023
- (onSubmit: (a: To) => Effect.Effect<OnSubmitA, never, RT>) =>
1029
+ (onSubmit: (a: To) => Effect.Effect<OnSubmitA, never, never>) =>
1024
1030
  async <T extends Promise<{ valid: boolean }>>(e: T) => {
1025
1031
  isLoading.value = true
1026
1032
  try {
1027
1033
  const r = await e
1028
1034
  if (!r.valid) return
1029
- return await runPromise(onSubmit(new s(await runPromise(parse(state.value)))))
1035
+ return await runPromise(onSubmit(new (s as any)(await runPromise(parse(state.value)))) as any)
1030
1036
  } finally {
1031
1037
  isLoading.value = false
1032
1038
  }
1033
1039
  }
1034
- const submit = submit1(onSubmit)
1040
+ const submit = submit1(onSubmit as any)
1035
1041
 
1036
1042
  watch(
1037
1043
  state,
@@ -1043,10 +1049,10 @@ export class LegacyMutationImpl<RT> {
1043
1049
  )
1044
1050
 
1045
1051
  const submitFromState = Effect.gen(function*() {
1046
- return yield* onSubmit(yield* parse(state.value))
1052
+ return yield* (onSubmit(yield* parse(state.value)) as any)
1047
1053
  })
1048
1054
 
1049
- const submitFromStatePromise = () => runPromise(submitFromState)
1055
+ const submitFromStatePromise = () => runPromise(submitFromState as any)
1050
1056
 
1051
1057
  return {
1052
1058
  fields,
@@ -1063,19 +1069,22 @@ export class LegacyMutationImpl<RT> {
1063
1069
  }
1064
1070
 
1065
1071
  // @effect-diagnostics-next-line missingEffectServiceDependency:off
1066
- export class LegacyMutation extends Effect.Service<LegacyMutation>()("LegacyMutation", {
1067
- effect: Effect.gen(function*() {
1072
+ export class LegacyMutation extends ServiceMap.Service<LegacyMutation>()("LegacyMutation", {
1073
+ make: Effect.gen(function*() {
1068
1074
  const intl = yield* I18n
1069
1075
  const toast = yield* Toast
1070
1076
 
1071
- return <R>(getRuntime: () => Runtime.Runtime<R>) => new LegacyMutationImpl(getRuntime, toast, intl)
1077
+ return <R>(getRuntime: () => ServiceMap.ServiceMap<R>) => new LegacyMutationImpl(getRuntime, toast, intl)
1072
1078
  })
1073
- }) {}
1079
+ }) {
1080
+ static readonly DefaultWithoutDependencies = Layer.effect(this, this.make)
1081
+ static readonly Default = this.DefaultWithoutDependencies
1082
+ }
1074
1083
 
1075
1084
  export type ClientFrom<M extends Requests> = RequestHandlers<never, never, M, M["meta"]["moduleName"]>
1076
1085
 
1077
1086
  export class QueryImpl<R> {
1078
- constructor(readonly getRuntime: () => Runtime.Runtime<R>) {
1087
+ constructor(readonly getRuntime: () => ServiceMap.ServiceMap<R>) {
1079
1088
  this.useQuery = makeQuery(this.getRuntime)
1080
1089
  }
1081
1090
  /**
@@ -1116,7 +1125,7 @@ export class QueryImpl<R> {
1116
1125
  ComputedRef<TData>,
1117
1126
  (
1118
1127
  options?: RefetchOptions
1119
- ) => Effect.Effect<QueryObserverResult<TData, KnownFiberFailure<E>>>,
1128
+ ) => Effect.Effect<QueryObserverResult<TData, E>>,
1120
1129
  UseQueryReturnType<any, any>
1121
1130
  ]
1122
1131
  >
@@ -1146,7 +1155,7 @@ export class QueryImpl<R> {
1146
1155
  ComputedRef<TData>,
1147
1156
  (
1148
1157
  options?: RefetchOptions
1149
- ) => Effect.Effect<QueryObserverResult<TData, KnownFiberFailure<E>>>,
1158
+ ) => Effect.Effect<QueryObserverResult<TData, E>>,
1150
1159
  UseQueryReturnType<any, any>
1151
1160
  ]
1152
1161
  >
@@ -1154,7 +1163,7 @@ export class QueryImpl<R> {
1154
1163
  } = <Arg, E, A, Request extends Req, Name extends string>(
1155
1164
  self: RequestHandlerWithInput<Arg, A, E, R, Request, Name> | RequestHandler<A, E, R, Request, Name>
1156
1165
  ) => {
1157
- const runPromise = Runtime.runPromise(this.getRuntime())
1166
+ const runPromise = Effect.runPromiseWith(this.getRuntime())
1158
1167
  const q = this.useQuery(self as any) as any
1159
1168
  return (argOrOptions?: any, options?: any) => {
1160
1169
  const [resultRef, latestRef, fetch, uqrt] = q(argOrOptions, { ...options, suspense: true } // experimental_prefetchInRender: true }
@@ -1171,12 +1180,10 @@ export class QueryImpl<R> {
1171
1180
  // what's the difference with just calling `fetch` ?
1172
1181
  // we will receive a CancelledError which we will have to ignore in our ErrorBoundary, otherwise the user ends up on an error page even if the user e.g cancelled a navigation
1173
1182
  const r = yield* Effect.tryPromise(() => uqrt.suspense()).pipe(
1174
- Effect.catchTag("UnknownException", (err) =>
1175
- Runtime.isFiberFailure(err.error)
1176
- ? Effect.failCause(err.error[Runtime.FiberFailureCauseId])
1177
- : isCancelledError(err.error)
1183
+ Effect.catchTag("UnknownError", (err) =>
1184
+ isCancelledError(err.cause)
1178
1185
  ? Effect.interrupt
1179
- : Effect.die(err.error))
1186
+ : Effect.die(err.cause))
1180
1187
  )
1181
1188
  if (!isMounted.value) {
1182
1189
  return yield* Effect.interrupt
@@ -1207,7 +1214,7 @@ export class QueryImpl<R> {
1207
1214
  }
1208
1215
 
1209
1216
  // somehow mrt.runtimeEffect doesnt work sync, but this workaround works fine? not sure why though as the layers are generally only sync
1210
- const managedRuntimeRt = <A, E>(mrt: ManagedRuntime.ManagedRuntime<A, E>) => mrt.runSync(Effect.runtime<A>())
1217
+ const managedRuntimeRt = <A, E>(mrt: ManagedRuntime.ManagedRuntime<A, E>) => mrt.runSync(Effect.services<A>())
1211
1218
 
1212
1219
  type Base = I18n | Toast
1213
1220
  type Mix = ApiClientFactory | Commander | LegacyMutation | Base
@@ -1218,7 +1225,7 @@ export const makeClient = <RT_, RTHooks>(
1218
1225
  rtHooks: Layer.Layer<RTHooks, never, Mix>
1219
1226
  ) => {
1220
1227
  type RT = RT_ | Mix
1221
- const getRt = Effect.runtime<RT>()
1228
+ const getRt = Effect.services<RT>()
1222
1229
  const getBaseRt = () => managedRuntimeRt(getBaseMrt())
1223
1230
  const makeCommand = makeUseCommand<RT, RTHooks>(rtHooks)
1224
1231
  const makeMutation = Effect.gen(function*() {
@@ -1226,9 +1233,9 @@ export const makeClient = <RT_, RTHooks>(
1226
1233
 
1227
1234
  return mut(() => getBaseMrt().runSync(getRt))
1228
1235
  })
1229
- let cmd: Effect.Effect.Success<typeof makeCommand>
1236
+ let cmd: Effect.Success<typeof makeCommand>
1230
1237
  const useCommand = () => cmd ??= getBaseMrt().runSync(makeCommand)
1231
- let mut: Effect.Effect.Success<typeof makeMutation>
1238
+ let mut: Effect.Success<typeof makeMutation>
1232
1239
  const getMutation = () => mut ??= getBaseMrt().runSync(makeMutation)
1233
1240
 
1234
1241
  let m: ReturnType<typeof useMutationInt>
@@ -1488,7 +1495,7 @@ export interface CommandBase<I = void, A = void> {
1488
1495
  label: string
1489
1496
  }
1490
1497
 
1491
- export interface EffectCommand<I = void, A = unknown, E = unknown> extends CommandBase<I, RuntimeFiber<A, E>> {}
1498
+ export interface EffectCommand<I = void, A = unknown, E = unknown> extends CommandBase<I, Fiber<A, E>> {}
1492
1499
 
1493
1500
  export interface CommandFromRequest<I extends abstract new(...args: any) => any, A = unknown, E = unknown>
1494
1501
  extends EffectCommand<ConstructorParameters<I>[0], A, E>
package/src/mutate.ts CHANGED
@@ -58,7 +58,7 @@ export function make<A, E, R>(self: Effect.Effect<A, E, R>) {
58
58
  .pipe(
59
59
  Effect.andThen(self),
60
60
  Effect.exit,
61
- Effect.andThen(Result.fromExit),
61
+ Effect.map(Result.fromExit),
62
62
  Effect.flatMap((r) => Effect.sync(() => result.value = r))
63
63
  )
64
64
 
@@ -118,7 +118,7 @@ export const asResult: {
118
118
  state.value = Result.initial(true)
119
119
  })
120
120
  .pipe(
121
- Effect.zipRight(Effect.suspend(() =>
121
+ Effect.andThen(Effect.suspend(() =>
122
122
  handler.pipe(
123
123
  Effect.exit,
124
124
  Effect.tap((exit) => Effect.sync(() => (state.value = Result.fromExit(exit))))
@@ -131,7 +131,7 @@ export const asResult: {
131
131
  state.value = Result.initial(true)
132
132
  })
133
133
  .pipe(
134
- Effect.zipRight(Effect.suspend(() =>
134
+ Effect.andThen(Effect.suspend(() =>
135
135
  handler(...args).pipe(
136
136
  Effect.exit,
137
137
  Effect.tap((exit) => Effect.sync(() => (state.value = Result.fromExit(exit))))
@@ -171,7 +171,7 @@ export const invalidateQueries = (
171
171
  Effect.annotateCurrentSpan({ queryKey, opts }),
172
172
  Effect.forEach(opts, (_) => invalidateQueries(_.filters, _.options), { concurrency: "inherit" })
173
173
  )
174
- .pipe(Effect.withSpan("client.query.invalidation", { captureStackTrace: false }))
174
+ .pipe(Effect.withSpan("client.query.invalidation", {}, { captureStackTrace: false }))
175
175
  }
176
176
 
177
177
  if (!queryKey) return Effect.void
@@ -187,12 +187,11 @@ export const invalidateQueries = (
187
187
  // TODO: should we do this in general on any mutation, regardless of invalidation?
188
188
  Effect.sleep(0)
189
189
  ),
190
- Effect.withSpan("client.query.invalidation", { captureStackTrace: false })
190
+ Effect.withSpan("client.query.invalidation", {}, { captureStackTrace: false })
191
191
  )
192
192
  })
193
193
 
194
- const handle = <A, E, R>(self: Effect.Effect<A, E, R>) =>
195
- Effect.tapBoth(self, { onFailure: () => invalidateCache, onSuccess: () => invalidateCache })
194
+ const handle = <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.ensuring(self, invalidateCache)
196
195
 
197
196
  return handle
198
197
  }