@effect-app/vue 1.20.7 → 1.21.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.
@@ -0,0 +1,500 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { flow, pipe, tuple } from "@effect-app/core/Function"
3
+ import { type MutationResult, Result, useSafeMutation } from "@effect-app/vue"
4
+ import * as Sentry from "@sentry/browser"
5
+ import { type MaybeRefOrGetter, type Pausable, useIntervalFn, type UseIntervalFnOptions } from "@vueuse/core"
6
+ import type { Either } from "effect-app"
7
+ import { Array, Cause, Effect, Match, Option, Runtime, S } from "effect-app"
8
+ import { type ApiConfig, type SupportedErrors } from "effect-app/client"
9
+ import type { HttpClient } from "effect-app/http"
10
+ import { Failure, Success } from "effect-app/Operations"
11
+ import { computed, type ComputedRef } from "vue"
12
+ import type { MakeIntlReturn } from "./makeIntl.js"
13
+
14
+ /**
15
+ * Use this after handling an error yourself, still continueing on the Error track, but the error will not be reported.
16
+ */
17
+ export class SuppressErrors extends Cause.YieldableError {
18
+ readonly _tag = "SuppressErrors"
19
+ }
20
+
21
+ type ResErrors = S.ParseResult.ParseError | SupportedErrors | SuppressErrors
22
+
23
+ export function pauseWhileProcessing(
24
+ iv: Pausable,
25
+ pmf: () => Promise<unknown>
26
+ ) {
27
+ return Promise
28
+ .resolve(iv.pause())
29
+ .then(() => pmf())
30
+ .finally(() => iv.resume())
31
+ }
32
+
33
+ export function useIntervalPauseWhileProcessing(
34
+ pmf: () => Promise<unknown>,
35
+ interval?: MaybeRefOrGetter<number>,
36
+ options?: Omit<UseIntervalFnOptions, "immediateCallback">
37
+ ) {
38
+ const iv = useIntervalFn(
39
+ () => pauseWhileProcessing(iv, pmf),
40
+ interval,
41
+ options ? { ...options, immediateCallback: false } : options
42
+ )
43
+ return {
44
+ isActive: iv.isActive
45
+ }
46
+ }
47
+
48
+ interface Opts<A> {
49
+ suppressErrorToast?: boolean
50
+ suppressSuccessToast?: boolean
51
+ successToast?: (a: A) => any
52
+ }
53
+ export const useSafeMutationWithState = <I, E, A>(self: {
54
+ handler: (i: I) => Effect<A, E, ApiConfig | HttpClient.HttpClient>
55
+ name: string
56
+ }) => {
57
+ const [a, b] = useSafeMutation(self)
58
+
59
+ return tuple(
60
+ computed(() => mutationResultToVue(a.value)),
61
+ b
62
+ )
63
+ }
64
+
65
+ export const withSuccess: {
66
+ <I, E extends ResErrors, A, X>(
67
+ self: {
68
+ handler: (i: I) => Effect<A, E, ApiConfig | HttpClient.HttpClient>
69
+ name: string
70
+ },
71
+ onSuccess: (a: A, i: I) => Promise<X>
72
+ ): {
73
+ handler: (i: I) => Effect<X, E, ApiConfig | HttpClient.HttpClient>
74
+ name: string
75
+ }
76
+ <E extends ResErrors, A, X>(
77
+ self: {
78
+ handler: Effect<A, E, ApiConfig | HttpClient.HttpClient>
79
+ name: string
80
+ },
81
+ onSuccess: (_: A) => Promise<X>
82
+ ): {
83
+ handler: Effect<X, E, ApiConfig | HttpClient.HttpClient>
84
+ name: string
85
+ }
86
+ } = (self: any, onSuccess: any): any => ({
87
+ ...self,
88
+ handler: typeof self.handler === "function"
89
+ ? (i: any) =>
90
+ pipe(
91
+ (
92
+ self.handler as (
93
+ i: any
94
+ ) => Effect<any, any, ApiConfig | HttpClient.HttpClient>
95
+ )(i),
96
+ Effect.flatMap((_) => Effect.promise(() => onSuccess(_, i)))
97
+ )
98
+ : Effect.flatMap(self.handler, (_) => Effect.promise(() => onSuccess(_)))
99
+ })
100
+
101
+ export const withSuccessE: {
102
+ <I, E extends ResErrors, A, E2, X>(
103
+ self: {
104
+ handler: (i: I) => Effect<A, E, ApiConfig | HttpClient.HttpClient>
105
+ name: string
106
+ },
107
+ onSuccessE: (_: A, i: I) => Effect<X, E2>
108
+ ): {
109
+ handler: (i: I) => Effect<X, E | E2, ApiConfig | HttpClient.HttpClient>
110
+ name: string
111
+ }
112
+ <E extends ResErrors, A, E2, X>(
113
+ self: {
114
+ handler: Effect<A, E, ApiConfig | HttpClient.HttpClient>
115
+ name: string
116
+ },
117
+ onSuccessE: (_: A) => Effect<X, E2>
118
+ ): {
119
+ handler: Effect<X, E | E2, ApiConfig | HttpClient.HttpClient>
120
+ name: string
121
+ }
122
+ } = (self: any, onSuccessE: any): any => {
123
+ return {
124
+ ...self,
125
+ handler: typeof self.handler === "function"
126
+ ? (i: any) =>
127
+ pipe(
128
+ self.handler(i),
129
+ Effect.flatMap((_) => onSuccessE(_, i))
130
+ )
131
+ : Effect.flatMap(self.handler, (_) => onSuccessE(_))
132
+ }
133
+ }
134
+
135
+ interface Res<A, E> {
136
+ readonly loading: boolean
137
+ readonly data: A | undefined
138
+ readonly error: E | undefined
139
+ }
140
+
141
+ type WithAction<A> = A & {
142
+ action: string
143
+ }
144
+
145
+ // computed() takes a getter function and returns a readonly reactive ref
146
+ // object for the returned value from the getter.
147
+ type Resp<I, E, A> = readonly [
148
+ ComputedRef<Res<A, E>>,
149
+ WithAction<(I: I) => Promise<void>>
150
+ ]
151
+
152
+ type ActResp<E, A> = readonly [
153
+ ComputedRef<Res<A, E>>,
154
+ WithAction<() => Promise<void>>
155
+ ]
156
+ function mutationResultToVue<A, E>(
157
+ mutationResult: MutationResult<A, E>
158
+ ): Res<A, E> {
159
+ switch (mutationResult._tag) {
160
+ case "Loading": {
161
+ return { loading: true, data: undefined, error: undefined }
162
+ }
163
+ case "Success": {
164
+ return {
165
+ loading: false,
166
+ data: mutationResult.data,
167
+ error: undefined
168
+ }
169
+ }
170
+ case "Error": {
171
+ return {
172
+ loading: false,
173
+ data: undefined,
174
+ error: mutationResult.error
175
+ }
176
+ }
177
+ case "Initial": {
178
+ return { loading: false, data: undefined, error: undefined }
179
+ }
180
+ }
181
+ }
182
+
183
+ const messages: Record<string, string | undefined> = {}
184
+
185
+ export const makeClient = <Locale extends string>(
186
+ intl: MakeIntlReturn<Locale>,
187
+ useToast: () => {
188
+ error: (message: string) => void
189
+ warning: (message: string) => void
190
+ success: (message: string) => void
191
+ }
192
+ ) => {
193
+ const { useIntl } = intl
194
+ const toast = useToast()
195
+ /**
196
+ * Pass a function that returns a Promise.
197
+ * Returns an execution function which reports errors as Toast.
198
+ */
199
+ function handleRequestWithToast<
200
+ E extends ResErrors,
201
+ A,
202
+ Args extends unknown[]
203
+ >(
204
+ f: (...args: Args) => Promise<Either<A, E>>,
205
+ action: string,
206
+ options: Opts<A> = { suppressErrorToast: false }
207
+ ) {
208
+ const { intl } = useIntl()
209
+ const message = messages[action] ?? action
210
+ const warnMessage = intl.value.formatMessage(
211
+ { id: "handle.with_warnings" },
212
+ { action: message }
213
+ )
214
+ const successMessage = intl.value.formatMessage(
215
+ { id: "handle.success" },
216
+ { action: message }
217
+ )
218
+ const errorMessage = intl.value.formatMessage(
219
+ { id: "handle.with_errors" },
220
+ { action: message }
221
+ )
222
+ return Object.assign(
223
+ flow(f, (p) =>
224
+ p.then(
225
+ (r) =>
226
+ r._tag === "Right"
227
+ ? S.is(Failure)(r.right)
228
+ ? Promise
229
+ .resolve(
230
+ toast.warning(
231
+ warnMessage + r.right.message
232
+ ? "\n" + r.right.message
233
+ : ""
234
+ )
235
+ )
236
+ .then((_) => {})
237
+ : Promise
238
+ .resolve(
239
+ toast.success(
240
+ successMessage
241
+ + (S.is(Success)(r.right) && r.right.message
242
+ ? "\n" + r.right.message
243
+ : "")
244
+ )
245
+ )
246
+ .then((_) => {})
247
+ : r.left._tag === "SuppressErrors"
248
+ ? Promise.resolve(void 0)
249
+ : Promise
250
+ .resolve(
251
+ !options.suppressErrorToast
252
+ && toast.error(`${errorMessage}:\n` + renderError(r.left))
253
+ )
254
+ .then((_) => {
255
+ console.warn(r.left, r.left.toString())
256
+ }),
257
+ (err) => {
258
+ if (
259
+ Cause.isInterruptedException(err)
260
+ || (Runtime.isFiberFailure(err)
261
+ && Cause.isInterruptedOnly(err[Runtime.FiberFailureCauseId]))
262
+ ) {
263
+ return
264
+ }
265
+ const extra = {
266
+ action,
267
+ message: `Unexpected Error trying to ${action}`
268
+ }
269
+ Sentry.captureException(err, {
270
+ extra
271
+ })
272
+ console.error(err, extra)
273
+
274
+ return toast.error(
275
+ intl.value.formatMessage(
276
+ { id: "handle.unexpected_error" },
277
+ {
278
+ action: message,
279
+ error: JSON.stringify(err, undefined, 2)
280
+ }
281
+ )
282
+ )
283
+ }
284
+ )),
285
+ { action }
286
+ )
287
+ }
288
+
289
+ function renderError(e: ResErrors): string {
290
+ const { intl } = useIntl()
291
+ return Match.value(e).pipe(
292
+ Match.tags({
293
+ // HttpErrorRequest: e =>
294
+ // intl.value.formatMessage(
295
+ // { id: "handle.request_error" },
296
+ // { error: `${e.error}` },
297
+ // ),
298
+ // HttpErrorResponse: e =>
299
+ // e.response.status >= 500 ||
300
+ // e.response.body._tag !== "Some" ||
301
+ // !e.response.body.value
302
+ // ? intl.value.formatMessage(
303
+ // { id: "handle.error_response" },
304
+ // {
305
+ // error: `${
306
+ // e.response.body._tag === "Some" && e.response.body.value
307
+ // ? parseError(e.response.body.value)
308
+ // : "Unknown"
309
+ // } (${e.response.status})`,
310
+ // },
311
+ // )
312
+ // : intl.value.formatMessage(
313
+ // { id: "handle.unexpected_error" },
314
+ // {
315
+ // error:
316
+ // JSON.stringify(e.response.body, undefined, 2) +
317
+ // "( " +
318
+ // e.response.status +
319
+ // ")",
320
+ // },
321
+ // ),
322
+ // ResponseError: e =>
323
+ // intl.value.formatMessage(
324
+ // { id: "handle.response_error" },
325
+ // { error: `${e.error}` },
326
+ // ),
327
+ ParseError: (e) => {
328
+ console.warn(e.toString())
329
+ return intl.value.formatMessage({ id: "validation.failed" })
330
+ }
331
+ }),
332
+ Match.orElse((e) =>
333
+ intl.value.formatMessage(
334
+ { id: "handle.unexpected_error" },
335
+ {
336
+ error: `${e.message ?? e._tag ?? e}`
337
+ }
338
+ )
339
+ )
340
+ )
341
+ }
342
+
343
+ /**
344
+ * Pass a function that returns an Effect, e.g from a client action, give it a name, and optionally pass an onSuccess callback.
345
+ * Returns a tuple with state ref and execution function which reports errors as Toast.
346
+ */
347
+ const useAndHandleMutation: {
348
+ <I, E extends ResErrors, A>(
349
+ self: {
350
+ handler: (i: I) => Effect<A, E, ApiConfig | HttpClient.HttpClient>
351
+ name: string
352
+ },
353
+ action: string,
354
+ options?: Opts<A>
355
+ ): Resp<I, E, A>
356
+ <E extends ResErrors, A>(
357
+ self: {
358
+ handler: Effect<A, E, ApiConfig | HttpClient.HttpClient>
359
+ name: string
360
+ },
361
+ action: string,
362
+ options?: Opts<A>
363
+ ): ActResp<E, A>
364
+ } = (self: any, action: any, options: any) => {
365
+ const [a, b] = useSafeMutation({
366
+ handler: Effect.isEffect(self.handler)
367
+ ? (pipe(
368
+ self.handler,
369
+ Effect.withSpan("mutation", { attributes: { action } })
370
+ ) as any)
371
+ : (...args: any[]) =>
372
+ pipe(
373
+ self.handler(...args),
374
+ Effect.withSpan("mutation", { attributes: { action } })
375
+ ),
376
+ name: self.name
377
+ })
378
+
379
+ return tuple(
380
+ computed(() => mutationResultToVue(a.value)),
381
+ handleRequestWithToast(b as any, action, options)
382
+ )
383
+ }
384
+
385
+ function makeUseAndHandleMutation(onSuccess: () => Promise<void>) {
386
+ return ((self: any, action: any, options: any) => {
387
+ return useAndHandleMutation(
388
+ {
389
+ handler: (typeof self.handler === "function"
390
+ ? (i: any) => Effect.tap(self.handler(i), () => Effect.promise(onSuccess))
391
+ : Effect.tap(self.handler, () => Effect.promise(onSuccess))) as any,
392
+ name: self.name
393
+ },
394
+ action,
395
+ options
396
+ )
397
+ }) as {
398
+ <I, E extends ResErrors, A>(
399
+ self: {
400
+ handler: (i: I) => Effect<A, E, ApiConfig | HttpClient.HttpClient>
401
+ name: string
402
+ },
403
+ action: string,
404
+ options?: Opts<A>
405
+ ): Resp<I, E, A>
406
+ <E extends ResErrors, A>(
407
+ self: {
408
+ handler: Effect<A, E, ApiConfig | HttpClient.HttpClient>
409
+ name: string
410
+ },
411
+ action: string,
412
+ options?: Opts<A>
413
+ ): ActResp<E, A>
414
+ }
415
+ }
416
+
417
+ return {
418
+ useAndHandleMutation,
419
+ makeUseAndHandleMutation,
420
+ handleRequestWithToast
421
+ }
422
+ }
423
+
424
+ export const mapHandler: {
425
+ <I, E, R, A, E2, A2, R2>(
426
+ self: {
427
+ handler: (i: I) => Effect<A, E, R>
428
+ name: string
429
+ mapPath: (i: I) => string
430
+ },
431
+ map: (i: I) => (handler: Effect<A, E, R>) => Effect<A2, E2, R2>
432
+ ): {
433
+ handler: (i: I) => Effect<A2, E2, R2>
434
+ name: string
435
+ mapPath: (i: I) => string
436
+ }
437
+ <E, A, R, E2, A2, R2>(
438
+ self: {
439
+ handler: Effect<A, E, R>
440
+ name: string
441
+ mapPath: string
442
+ },
443
+ map: (handler: Effect<A, E, R>) => Effect<A2, E2, R2>
444
+ ): {
445
+ handler: Effect<A2, E2, R2>
446
+ name: string
447
+ mapPath: string
448
+ }
449
+ } = (self: any, map: any): any => ({
450
+ ...self,
451
+ handler: typeof self.handler === "function"
452
+ ? (i: any) => map(i)((self.handler as (i: any) => Effect<any, any, any>)(i))
453
+ : map(self.handler)
454
+ })
455
+
456
+ export function composeQueries<
457
+ R extends Record<string, Result.Result<any, any>>
458
+ >(
459
+ results: R,
460
+ renderPreviousOnFailure?: boolean
461
+ ): Result.Result<
462
+ {
463
+ [Property in keyof R]: R[Property] extends Result.Result<infer A, any> ? A
464
+ : never
465
+ },
466
+ {
467
+ [Property in keyof R]: R[Property] extends Result.Result<any, infer E> ? E
468
+ : never
469
+ }[keyof R]
470
+ > {
471
+ const values = renderPreviousOnFailure
472
+ ? Object.values(results).map(orPrevious)
473
+ : Object.values(results)
474
+ const error = values.find(Result.isFailure)
475
+ if (error) {
476
+ return error
477
+ }
478
+ const initial = Array.findFirst(values, (x) => x._tag === "Initial" ? Option.some(x) : Option.none())
479
+ if (initial.value !== undefined) {
480
+ return initial.value
481
+ }
482
+ const loading = Array.findFirst(values, (x) => Result.isInitial(x) && x.waiting ? Option.some(x) : Option.none())
483
+ if (loading.value !== undefined) {
484
+ return loading.value
485
+ }
486
+
487
+ const isRefreshing = values.some((x) => x.waiting)
488
+
489
+ const r = Object.entries(results).reduce((prev, [key, value]) => {
490
+ prev[key] = Result.value(value).value
491
+ return prev
492
+ }, {} as any)
493
+ return Result.success(r, isRefreshing)
494
+ }
495
+
496
+ function orPrevious<E, A>(result: Result.Result<A, E>) {
497
+ return Result.isFailure(result) && Option.isSome(result.previousValue)
498
+ ? Result.success(result.previousValue.value, result.waiting)
499
+ : result
500
+ }
@@ -0,0 +1,9 @@
1
+ import { inject, type InjectionKey, provide } from "vue"
2
+
3
+ export const makeContext = <T>(def: T) => {
4
+ const key = Symbol() as InjectionKey<T>
5
+ return {
6
+ use: () => inject(key, def),
7
+ provide: (locale: T) => provide(key, locale)
8
+ }
9
+ }
@@ -0,0 +1,60 @@
1
+ /* eslint-disable @typescript-eslint/no-empty-object-type */
2
+ import { createIntl, createIntlCache, type IntlShape } from "@formatjs/intl"
3
+ import { typedKeysOf } from "effect-app/utils"
4
+ import type { FormatXMLElementFn, PrimitiveType } from "intl-messageformat"
5
+ import type { Ref } from "vue"
6
+ import { computed, ref, watch } from "vue"
7
+ import { translate } from "./form.js"
8
+ import { makeContext } from "./makeContext.js"
9
+
10
+ export interface MakeIntlReturn<Locale extends string> extends ReturnType<typeof makeIntl<Locale>> {}
11
+
12
+ export const makeIntl = <Locale extends string>(
13
+ messages: Record<Locale, Record<string, string>>,
14
+ defaultLocale: NoInfer<Locale>
15
+ ) => {
16
+ const intlCache = createIntlCache()
17
+
18
+ const intls = typedKeysOf(messages).reduce(
19
+ (acc, cur) => {
20
+ acc[cur] = createIntl<Locale>(
21
+ {
22
+ defaultLocale,
23
+ locale: cur,
24
+ messages: messages[cur]
25
+ },
26
+ intlCache
27
+ )
28
+ return acc
29
+ },
30
+ {} as Record<Locale, IntlShape<Locale>>
31
+ )
32
+
33
+ const LocaleContext = makeContext(ref<Locale>(defaultLocale) as Ref<Locale>)
34
+
35
+ const useIntl = () => {
36
+ const locale = LocaleContext.use()
37
+
38
+ const trans = (
39
+ id: keyof (typeof messages)[Locale],
40
+ values?: Record<
41
+ string,
42
+ PrimitiveType | FormatXMLElementFn<string, string>
43
+ >
44
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
45
+ ) => intls[locale.value].formatMessage({ id: id as any }, values)
46
+
47
+ const intl = computed(() => intls[locale.value])
48
+ watch(
49
+ locale,
50
+ (locale) => {
51
+ const intl = intls[locale]
52
+ translate.value = intl.formatMessage
53
+ },
54
+ { immediate: true }
55
+ )
56
+
57
+ return { locale, trans, intl }
58
+ }
59
+ return { useIntl, LocaleContext }
60
+ }
@@ -0,0 +1,37 @@
1
+ // packages/vue/vitest.config.ts
2
+ import { defineConfig } from "file:///Users/patrickroza/pj/effect-app/libs/node_modules/.pnpm/vite@5.2.6_@types+node@20.11.30/node_modules/vite/dist/node/index.js";
3
+
4
+ // vite.config.base.ts
5
+ import path from "path";
6
+ import fs from "fs";
7
+ var __vite_injected_original_dirname = "/Users/patrickroza/pj/effect-app/libs";
8
+ function makeConfig(dirName) {
9
+ const prefix = path.resolve(__vite_injected_original_dirname, "packages");
10
+ const packages = fs.readdirSync(prefix).map((f) => prefix + "/" + f).filter((f) => fs.lstatSync(f).isDirectory());
11
+ const cfg = {
12
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
13
+ //plugins: [autoImport],
14
+ test: {
15
+ include: ["./test/**/*.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
16
+ reporters: "verbose",
17
+ globals: true
18
+ },
19
+ resolve: {
20
+ alias: packages.reduce((acc, cur) => {
21
+ acc[JSON.parse(fs.readFileSync(cur + "/package.json", "utf-8")).name] = path.resolve(cur, cur.endsWith("core") ? "dist" : "src");
22
+ return acc;
23
+ }, {})
24
+ // "@effect-app/core/Prelude": path.join(__dirname, "packages/core/src/Prelude.code.ts")
25
+ }
26
+ };
27
+ console.log(cfg);
28
+ return cfg;
29
+ }
30
+
31
+ // packages/vue/vitest.config.ts
32
+ var __vite_injected_original_dirname2 = "/Users/patrickroza/pj/effect-app/libs/packages/vue";
33
+ var vitest_config_default = defineConfig(makeConfig(__vite_injected_original_dirname2));
34
+ export {
35
+ vitest_config_default as default
36
+ };
37
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsicGFja2FnZXMvdnVlL3ZpdGVzdC5jb25maWcudHMiLCAidml0ZS5jb25maWcuYmFzZS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiY29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2Rpcm5hbWUgPSBcIi9Vc2Vycy9wYXRyaWNrcm96YS9wai9lZmZlY3QtYXBwL2xpYnMvcGFja2FnZXMvdnVlXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCIvVXNlcnMvcGF0cmlja3JvemEvcGovZWZmZWN0LWFwcC9saWJzL3BhY2thZ2VzL3Z1ZS92aXRlc3QuY29uZmlnLnRzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9Vc2Vycy9wYXRyaWNrcm96YS9wai9lZmZlY3QtYXBwL2xpYnMvcGFja2FnZXMvdnVlL3ZpdGVzdC5jb25maWcudHNcIjsvLy8gPHJlZmVyZW5jZSB0eXBlcz1cInZpdGVzdFwiIC8+XG5pbXBvcnQgeyBkZWZpbmVDb25maWcgfSBmcm9tIFwidml0ZVwiXG5pbXBvcnQgbWFrZUNvbmZpZyBmcm9tIFwiLi4vLi4vdml0ZS5jb25maWcuYmFzZVwiXG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyhtYWtlQ29uZmlnKF9fZGlybmFtZSkpXG4iLCAiY29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2Rpcm5hbWUgPSBcIi9Vc2Vycy9wYXRyaWNrcm96YS9wai9lZmZlY3QtYXBwL2xpYnNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIi9Vc2Vycy9wYXRyaWNrcm96YS9wai9lZmZlY3QtYXBwL2xpYnMvdml0ZS5jb25maWcuYmFzZS50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vVXNlcnMvcGF0cmlja3JvemEvcGovZWZmZWN0LWFwcC9saWJzL3ZpdGUuY29uZmlnLmJhc2UudHNcIjsvLy8gPHJlZmVyZW5jZSB0eXBlcz1cInZpdGVzdFwiIC8+XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiXG5pbXBvcnQgZnMgZnJvbSBcImZzXCJcbmltcG9ydCBBdXRvSW1wb3J0IGZyb20gXCJ1bnBsdWdpbi1hdXRvLWltcG9ydC92aXRlXCJcbmltcG9ydCB7IGRlZmluZUNvbmZpZyB9IGZyb20gXCJ2aXRlc3QvY29uZmlnXCJcblxuLy8gY29uc3QgYXV0b0ltcG9ydCA9IEF1dG9JbXBvcnQoe1xuLy8gICBkdHM6IFwiLi90ZXN0L2F1dG8taW1wb3J0cy5kLnRzXCIsXG4vLyAgIC8vIGluY2x1ZGU6IFtcbi8vICAgLy8gICAvXFwudGVzdFxcLlt0al1zeD8kLyAvLyAudHMsIC50c3gsIC5qcywgLmpzeFxuLy8gICAvLyBdLFxuLy8gICBpbXBvcnRzOiBbXG4vLyAgICAgXCJ2aXRlc3RcIlxuLy8gICBdXG4vLyB9KVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBtYWtlQ29uZmlnKGRpck5hbWU/OiBzdHJpbmcpIHtcbiAgY29uc3QgcHJlZml4ID0gcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgXCJwYWNrYWdlc1wiKVxuICBjb25zdCBwYWNrYWdlcyA9IGZzLnJlYWRkaXJTeW5jKHByZWZpeCkubWFwKGYgPT4gcHJlZml4ICsgXCIvXCIgKyBmKS5maWx0ZXIoZiA9PiBmcy5sc3RhdFN5bmMoZikuaXNEaXJlY3RvcnkoKSApXG4gIGNvbnN0IGNmZyA9IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXZhci1yZXF1aXJlc1xuICAgIC8vcGx1Z2luczogW2F1dG9JbXBvcnRdLFxuICAgIHRlc3Q6IHtcbiAgICAgIGluY2x1ZGU6ICBbXCIuL3Rlc3QvKiovKi50ZXN0LntqcyxtanMsY2pzLHRzLG10cyxjdHMsanN4LHRzeH1cIl0sXG4gICAgICByZXBvcnRlcnM6IFwidmVyYm9zZVwiLFxuICAgICAgZ2xvYmFsczogdHJ1ZVxuICAgIH0sXG4gICAgcmVzb2x2ZToge1xuICAgICAgYWxpYXM6IHBhY2thZ2VzLnJlZHVjZSgoYWNjLCBjdXIpID0+IHsgLy8gd29ya2Fyb3VuZCBmb3IgL1ByZWx1ZGUgaXNzdWVcbiAgICAgIGFjY1tKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhjdXIgKyBcIi9wYWNrYWdlLmpzb25cIiwgXCJ1dGYtOFwiKSkubmFtZV0gPSBwYXRoLnJlc29sdmUoY3VyLCBjdXIuZW5kc1dpdGgoXCJjb3JlXCIpID8gXCJkaXN0XCIgOiBcInNyY1wiKVxuICAgICAgcmV0dXJuIGFjY1xuICAgIH0sIHsgfSkgLy8gXCJAZWZmZWN0LWFwcC9jb3JlL1ByZWx1ZGVcIjogcGF0aC5qb2luKF9fZGlybmFtZSwgXCJwYWNrYWdlcy9jb3JlL3NyYy9QcmVsdWRlLmNvZGUudHNcIilcbiAgfVxuICB9XG4gIGNvbnNvbGUubG9nKGNmZylcbiAgcmV0dXJuIGNmZ1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUNBLFNBQVMsb0JBQW9COzs7QUNBN0IsT0FBTyxVQUFVO0FBQ2pCLE9BQU8sUUFBUTtBQUZmLElBQU0sbUNBQW1DO0FBZ0IxQixTQUFSLFdBQTRCLFNBQWtCO0FBQ25ELFFBQU0sU0FBUyxLQUFLLFFBQVEsa0NBQVcsVUFBVTtBQUNqRCxRQUFNLFdBQVcsR0FBRyxZQUFZLE1BQU0sRUFBRSxJQUFJLE9BQUssU0FBUyxNQUFNLENBQUMsRUFBRSxPQUFPLE9BQUssR0FBRyxVQUFVLENBQUMsRUFBRSxZQUFZLENBQUU7QUFDN0csUUFBTSxNQUFNO0FBQUE7QUFBQTtBQUFBLElBR1YsTUFBTTtBQUFBLE1BQ0osU0FBVSxDQUFDLGtEQUFrRDtBQUFBLE1BQzdELFdBQVc7QUFBQSxNQUNYLFNBQVM7QUFBQSxJQUNYO0FBQUEsSUFDQSxTQUFTO0FBQUEsTUFDUCxPQUFPLFNBQVMsT0FBTyxDQUFDLEtBQUssUUFBUTtBQUNyQyxZQUFJLEtBQUssTUFBTSxHQUFHLGFBQWEsTUFBTSxpQkFBaUIsT0FBTyxDQUFDLEVBQUUsSUFBSSxJQUFJLEtBQUssUUFBUSxLQUFLLElBQUksU0FBUyxNQUFNLElBQUksU0FBUyxLQUFLO0FBQy9ILGVBQU87QUFBQSxNQUNULEdBQUcsQ0FBRSxDQUFDO0FBQUE7QUFBQSxJQUNSO0FBQUEsRUFDQTtBQUNBLFVBQVEsSUFBSSxHQUFHO0FBQ2YsU0FBTztBQUNUOzs7QURwQ0EsSUFBTUEsb0NBQW1DO0FBSXpDLElBQU8sd0JBQVEsYUFBYSxXQUFXQyxpQ0FBUyxDQUFDOyIsCiAgIm5hbWVzIjogWyJfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZGlybmFtZSIsICJfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZGlybmFtZSJdCn0K
@@ -0,0 +1,37 @@
1
+ // packages/vue/vitest.config.ts
2
+ import { defineConfig } from "file:///Users/patrickroza/pj/effect-app/libs/node_modules/.pnpm/vite@5.2.6_@types+node@20.11.30/node_modules/vite/dist/node/index.js";
3
+
4
+ // vite.config.base.ts
5
+ import path from "path";
6
+ import fs from "fs";
7
+ var __vite_injected_original_dirname = "/Users/patrickroza/pj/effect-app/libs";
8
+ function makeConfig(dirName) {
9
+ const prefix = path.resolve(__vite_injected_original_dirname, "packages");
10
+ const packages = fs.readdirSync(prefix).map((f) => prefix + "/" + f).filter((f) => fs.lstatSync(f).isDirectory());
11
+ const cfg = {
12
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
13
+ //plugins: [autoImport],
14
+ test: {
15
+ include: ["./test/**/*.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
16
+ reporters: "verbose",
17
+ globals: true
18
+ },
19
+ resolve: {
20
+ alias: packages.reduce((acc, cur) => {
21
+ acc[JSON.parse(fs.readFileSync(cur + "/package.json", "utf-8")).name] = path.resolve(cur, cur.endsWith("core") ? "dist" : "src");
22
+ return acc;
23
+ }, {})
24
+ // "@effect-app/core/Prelude": path.join(__dirname, "packages/core/src/Prelude.code.ts")
25
+ }
26
+ };
27
+ console.log(cfg);
28
+ return cfg;
29
+ }
30
+
31
+ // packages/vue/vitest.config.ts
32
+ var __vite_injected_original_dirname2 = "/Users/patrickroza/pj/effect-app/libs/packages/vue";
33
+ var vitest_config_default = defineConfig(makeConfig(__vite_injected_original_dirname2));
34
+ export {
35
+ vitest_config_default as default
36
+ };
37
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsicGFja2FnZXMvdnVlL3ZpdGVzdC5jb25maWcudHMiLCAidml0ZS5jb25maWcuYmFzZS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiY29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2Rpcm5hbWUgPSBcIi9Vc2Vycy9wYXRyaWNrcm96YS9wai9lZmZlY3QtYXBwL2xpYnMvcGFja2FnZXMvdnVlXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCIvVXNlcnMvcGF0cmlja3JvemEvcGovZWZmZWN0LWFwcC9saWJzL3BhY2thZ2VzL3Z1ZS92aXRlc3QuY29uZmlnLnRzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9Vc2Vycy9wYXRyaWNrcm96YS9wai9lZmZlY3QtYXBwL2xpYnMvcGFja2FnZXMvdnVlL3ZpdGVzdC5jb25maWcudHNcIjsvLy8gPHJlZmVyZW5jZSB0eXBlcz1cInZpdGVzdFwiIC8+XG5pbXBvcnQgeyBkZWZpbmVDb25maWcgfSBmcm9tIFwidml0ZVwiXG5pbXBvcnQgbWFrZUNvbmZpZyBmcm9tIFwiLi4vLi4vdml0ZS5jb25maWcuYmFzZVwiXG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyhtYWtlQ29uZmlnKF9fZGlybmFtZSkpXG4iLCAiY29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2Rpcm5hbWUgPSBcIi9Vc2Vycy9wYXRyaWNrcm96YS9wai9lZmZlY3QtYXBwL2xpYnNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIi9Vc2Vycy9wYXRyaWNrcm96YS9wai9lZmZlY3QtYXBwL2xpYnMvdml0ZS5jb25maWcuYmFzZS50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vVXNlcnMvcGF0cmlja3JvemEvcGovZWZmZWN0LWFwcC9saWJzL3ZpdGUuY29uZmlnLmJhc2UudHNcIjsvLy8gPHJlZmVyZW5jZSB0eXBlcz1cInZpdGVzdFwiIC8+XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiXG5pbXBvcnQgZnMgZnJvbSBcImZzXCJcbmltcG9ydCBBdXRvSW1wb3J0IGZyb20gXCJ1bnBsdWdpbi1hdXRvLWltcG9ydC92aXRlXCJcbmltcG9ydCB7IGRlZmluZUNvbmZpZyB9IGZyb20gXCJ2aXRlc3QvY29uZmlnXCJcblxuLy8gY29uc3QgYXV0b0ltcG9ydCA9IEF1dG9JbXBvcnQoe1xuLy8gICBkdHM6IFwiLi90ZXN0L2F1dG8taW1wb3J0cy5kLnRzXCIsXG4vLyAgIC8vIGluY2x1ZGU6IFtcbi8vICAgLy8gICAvXFwudGVzdFxcLlt0al1zeD8kLyAvLyAudHMsIC50c3gsIC5qcywgLmpzeFxuLy8gICAvLyBdLFxuLy8gICBpbXBvcnRzOiBbXG4vLyAgICAgXCJ2aXRlc3RcIlxuLy8gICBdXG4vLyB9KVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBtYWtlQ29uZmlnKGRpck5hbWU/OiBzdHJpbmcpIHtcbiAgY29uc3QgcHJlZml4ID0gcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgXCJwYWNrYWdlc1wiKVxuICBjb25zdCBwYWNrYWdlcyA9IGZzLnJlYWRkaXJTeW5jKHByZWZpeCkubWFwKGYgPT4gcHJlZml4ICsgXCIvXCIgKyBmKS5maWx0ZXIoZiA9PiBmcy5sc3RhdFN5bmMoZikuaXNEaXJlY3RvcnkoKSApXG4gIGNvbnN0IGNmZyA9IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXZhci1yZXF1aXJlc1xuICAgIC8vcGx1Z2luczogW2F1dG9JbXBvcnRdLFxuICAgIHRlc3Q6IHtcbiAgICAgIGluY2x1ZGU6ICBbXCIuL3Rlc3QvKiovKi50ZXN0LntqcyxtanMsY2pzLHRzLG10cyxjdHMsanN4LHRzeH1cIl0sXG4gICAgICByZXBvcnRlcnM6IFwidmVyYm9zZVwiLFxuICAgICAgZ2xvYmFsczogdHJ1ZVxuICAgIH0sXG4gICAgcmVzb2x2ZToge1xuICAgICAgYWxpYXM6IHBhY2thZ2VzLnJlZHVjZSgoYWNjLCBjdXIpID0+IHsgLy8gd29ya2Fyb3VuZCBmb3IgL1ByZWx1ZGUgaXNzdWVcbiAgICAgIGFjY1tKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhjdXIgKyBcIi9wYWNrYWdlLmpzb25cIiwgXCJ1dGYtOFwiKSkubmFtZV0gPSBwYXRoLnJlc29sdmUoY3VyLCBjdXIuZW5kc1dpdGgoXCJjb3JlXCIpID8gXCJkaXN0XCIgOiBcInNyY1wiKVxuICAgICAgcmV0dXJuIGFjY1xuICAgIH0sIHsgfSkgLy8gXCJAZWZmZWN0LWFwcC9jb3JlL1ByZWx1ZGVcIjogcGF0aC5qb2luKF9fZGlybmFtZSwgXCJwYWNrYWdlcy9jb3JlL3NyYy9QcmVsdWRlLmNvZGUudHNcIilcbiAgfVxuICB9XG4gIGNvbnNvbGUubG9nKGNmZylcbiAgcmV0dXJuIGNmZ1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUNBLFNBQVMsb0JBQW9COzs7QUNBN0IsT0FBTyxVQUFVO0FBQ2pCLE9BQU8sUUFBUTtBQUZmLElBQU0sbUNBQW1DO0FBZ0IxQixTQUFSLFdBQTRCLFNBQWtCO0FBQ25ELFFBQU0sU0FBUyxLQUFLLFFBQVEsa0NBQVcsVUFBVTtBQUNqRCxRQUFNLFdBQVcsR0FBRyxZQUFZLE1BQU0sRUFBRSxJQUFJLE9BQUssU0FBUyxNQUFNLENBQUMsRUFBRSxPQUFPLE9BQUssR0FBRyxVQUFVLENBQUMsRUFBRSxZQUFZLENBQUU7QUFDN0csUUFBTSxNQUFNO0FBQUE7QUFBQTtBQUFBLElBR1YsTUFBTTtBQUFBLE1BQ0osU0FBVSxDQUFDLGtEQUFrRDtBQUFBLE1BQzdELFdBQVc7QUFBQSxNQUNYLFNBQVM7QUFBQSxJQUNYO0FBQUEsSUFDQSxTQUFTO0FBQUEsTUFDUCxPQUFPLFNBQVMsT0FBTyxDQUFDLEtBQUssUUFBUTtBQUNyQyxZQUFJLEtBQUssTUFBTSxHQUFHLGFBQWEsTUFBTSxpQkFBaUIsT0FBTyxDQUFDLEVBQUUsSUFBSSxJQUFJLEtBQUssUUFBUSxLQUFLLElBQUksU0FBUyxNQUFNLElBQUksU0FBUyxLQUFLO0FBQy9ILGVBQU87QUFBQSxNQUNULEdBQUcsQ0FBRSxDQUFDO0FBQUE7QUFBQSxJQUNSO0FBQUEsRUFDQTtBQUNBLFVBQVEsSUFBSSxHQUFHO0FBQ2YsU0FBTztBQUNUOzs7QURwQ0EsSUFBTUEsb0NBQW1DO0FBSXpDLElBQU8sd0JBQVEsYUFBYSxXQUFXQyxpQ0FBUyxDQUFDOyIsCiAgIm5hbWVzIjogWyJfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZGlybmFtZSIsICJfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZGlybmFtZSJdCn0K