Skip to content

Commit

Permalink
V2 (#45)
Browse files Browse the repository at this point in the history
* Upgrade pothos v4

* Improve type
  • Loading branch information
iamchanii committed Jul 17, 2024
1 parent 628d4ab commit 03646c5
Show file tree
Hide file tree
Showing 11 changed files with 378 additions and 669 deletions.
5 changes: 5 additions & 0 deletions .changeset/four-apricots-grow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"pothos-plugin-effect": major
---

Update pothos v4
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
"@changesets/cli": "^2.27.1"
},
"resolutions": {
"@vitest/coverage-v8": "1.5.2",
"vitest": "1.5.2",
"@vitest/coverage-v8": "2",
"vitest": "2",
"nanobundle": "2.0.0",
"typescript": "5.5.0-beta",
"graphql": "*"
Expand Down
239 changes: 9 additions & 230 deletions packages/pothos-plugin-effect/MIGRATION.md
Original file line number Diff line number Diff line change
@@ -1,235 +1,14 @@
# Migration from v0.x
# Migration from v1

The 1.0 release contains a large number of breaking changes. If you're using pothos-plugin-effect from 0.x (thanksfully), follow the instructions below.
## Breaking API Changes

## `t.effect` is not field builder.
### Renamed options

`t.effect` is provided as a utility function rather than in the field builder. Use `t.effect` inside any kind of Pothos field resolver function to resolve the Effect.
The name of the plugin option field has been changed to `effect` to be more consistent with other offical Pothos plugins.

<table>
<thead>
<tr>
<th><code>Before (0.x)</code></th>
<th><code>After (1.0.0 ~)</code></th>
</thead>
<tbody>
<tr>
<td>

```ts
t.effect({
type: "Int",
effect: {},
resolve: () => Effect.succeed(1),
});
```

</td>
<td>

```ts
t.int({
resolve: () => t.effect(Effect.succeed(1)),
});

t.string({
resolve: () => t.effect(Effect.succeed("Hello, World!")),
});

t.field({
type: "Float",
nullable: true,
resolve: () => t.effect(Effect.succeedNone),
});
```

</td>
</tr>
</tbody>
</table>

## Removed service/context/layer configuration options at field level.

Instead, you can [configure a custom effect runtime](./README.md#configure-custom-runtime).

<table>
<thead>
<tr>
<th><code>Before (0.x)</code></th>
<th><code>After (1.0.0 ~)</code></th>
</thead>
<tbody>
<tr>
<td>

```ts
t.effect({
type: User,
effect: {
services: [
UserService,
UserService.of({
/* ... */
}),
],
contexts: [
/* ... */
],
layers: [
/* ... */
],
},
resolve: () =>
Effect.gen(function* (_) {
const userService = yield* _(UserService);

return yield* _(userService.getUserOrThrow());
}),
});
```diff
const builder = new SchemaBuilder<{}>({
- effectOptions: {...}
+ effect: {...}
})
```

</td>
<td>

```ts
declare const effectRuntime: Runtime.Runtime<UserService>;

const builder = new SchemaBuilder<{
EffectRuntime: typeof effectRuntime;
}>({
plugins: [EffectPlugin],
effectOptions: { effectRuntime },
});

// in builder:

t.field({
type: User,
resolve: () =>
t.effect(
Effect.gen(function* (_) {
const userService = yield* _(UserService);

return yield* _(userService.getUserOrThrow());
})
),
});
```

</td>
</tr>
</tbody>
</table>

## Removed `t.effectConnection`

Instead, you can directly use the `resolveArrayConnection`/`resolveCursorConnection`/`resolveOffsetConnection` which imported from [`@pothos/plugin-relay`](https://pothos-graphql.dev/docs/plugins/relay), with `t.effect`. Below is an example code for using `resolveArrayConnection`:

<table>
<thead>
<tr>
<th><code>Before (0.x)</code></th>
<th><code>After (1.0.0 ~)</code></th>
</thead>
<tbody>
<tr>
<td>

```ts
t.effectConnection({
type: "Int",
effect: {
/* ... */
},
resolve: () => Effect.succeed([1, 2, 3, 4]),
});
```

</td>
<td>

```ts
t.connection({
type: "Int",
resolve: async (_root, args) =>
resolveArrayConnection(
{ args },
await t.effect(Effect.succeed([1, 2, 3, 4]))
),
});

t.connection({
type: "Int",
resolve: async (_root, args) =>
resolveCursorConnection(
{ args, toCursor: (id) => id },
(_params) => t.effect(Effect.succeed([1, 2, 3, 4]))
),
});

t.connection({
type: "Int",
resolve: async (_root, args) =>
resolveOffsetConnection({ args }, (_params) =>
t.effect(Effect.succeed([1, 2, 3, 4]))
),
});
```

</td>
</tr>
</tbody>
</table>

## Removed `t.prismaEffect` (aka Prisma Integration)

`t.effect` works even if the end result of the Effect is a Promise.

<table>
<thead>
<tr>
<th><code>Before (0.x)</code></th>
<th><code>After (1.0.0 ~)</code></th>
</thead>
<tbody>
<tr>
<td>

```ts
t.prismaEffect({
type: "User",
effect: {
/* ... */
},
resolve: (query) =>
PrismaEffect.user.findFirstOrThrow({
...query,
}),
});
```

</td>
<td>

```ts
t.prismaField({
type: "User",
resolve: (query) =>
t.effect(
Effect.succeed(
prisma.user.findFirstOrThrow({
...query,
})
)
),
});
```

</td>
</tr>
</tbody>
</table>

## Removed error type inferring

Removed `errors.types` inference functionality provided by integration with the errors plugin.
12 changes: 6 additions & 6 deletions packages/pothos-plugin-effect/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@
},
"license": "MIT",
"devDependencies": {
"@pothos/core": "3.41.0",
"@pothos/plugin-errors": "3.11.1",
"@pothos/plugin-prisma": "3.63.1",
"@pothos/plugin-relay": "3.46.0",
"@pothos/plugin-with-input": "^3.10.1",
"@pothos/core": "^4.0.2",
"@pothos/plugin-errors": "^4.0.2",
"@pothos/plugin-prisma": "^4.0.5",
"@pothos/plugin-relay": "^4.0.2",
"@pothos/plugin-with-input": "^4.0.2",
"@prisma/client": "5.9.1",
"@types/better-sqlite3": "^7.6.9",
"@types/node": "20.11.13",
Expand All @@ -59,7 +59,7 @@
"vitest": "*"
},
"peerDependencies": {
"@pothos/core": "^3",
"@pothos/core": "^4",
"effect": ">=3.0.0 <4",
"graphql": "^16 || ^17"
},
Expand Down
2 changes: 2 additions & 0 deletions packages/pothos-plugin-effect/prisma/pothos-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default interface PrismaTypes {
posts: {
Shape: Post[];
Name: "Post";
Nullable: false;
};
};
};
Expand All @@ -36,6 +37,7 @@ export default interface PrismaTypes {
author: {
Shape: User;
Name: "User";
Nullable: false;
};
};
};
Expand Down
28 changes: 20 additions & 8 deletions packages/pothos-plugin-effect/src/field-builder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FieldKind, RootFieldBuilder, SchemaTypes } from '@pothos/core';
import { Runtime } from 'effect';
import { executeEffect, executeStream } from 'effect-utils';
import { Effect, Runtime } from 'effect';
import { executeEffect, executeStream, isStream } from 'effect-utils';

const fieldBuilderProto =
RootFieldBuilder.prototype as PothosSchemaTypes.RootFieldBuilder<
Expand All @@ -11,14 +11,14 @@ const fieldBuilderProto =

fieldBuilderProto.executeEffect = function (effectFieldResult) {
const effectRuntime =
this.builder.options.effectOptions?.effectRuntime ?? Runtime.defaultRuntime;
this.builder.options.effect?.effectRuntime ?? Runtime.defaultRuntime;

return executeEffect(effectFieldResult, effectRuntime) as never;
};

fieldBuilderProto.executeStream = function (effectFieldResult) {
const effectRuntime =
this.builder.options.effectOptions?.effectRuntime ?? Runtime.defaultRuntime;
this.builder.options.effect?.effectRuntime ?? Runtime.defaultRuntime;

return executeStream(effectFieldResult, effectRuntime) as never;
};
Expand All @@ -31,8 +31,13 @@ fieldBuilderProto.effect = function (options) {
if ('resolve' in options) {
const effectFieldResult = options.resolve(root, args, context, info);

// @ts-ignore
return this.executeEffect(effectFieldResult);
if (Effect.isEffect(effectFieldResult)) {
return this.executeEffect(effectFieldResult);
}

if (isStream(effectFieldResult)) {
return this.executeStream(effectFieldResult);
}
}
},
// @ts-ignore
Expand All @@ -56,8 +61,15 @@ fieldBuilderProto.effectWithInput = function (options) {
if ('resolve' in options) {
const effectFieldResult = options.resolve(root, args, context, info);

// @ts-ignore
return this.executeEffect(effectFieldResult);
if (Effect.isEffect(effectFieldResult)) {
// @ts-ignore
return this.executeEffect(effectFieldResult);
}

if (isStream(effectFieldResult)) {
// @ts-ignore
return this.executeStream(effectFieldResult);
}
}
},
// @ts-ignore
Expand Down
Loading

0 comments on commit 03646c5

Please sign in to comment.