Code Monkey home page Code Monkey logo

pothos-plugin-effect's Introduction

pothos-plugin-effect

Seamless integration between the Pothos GraphQL and Effect.

Hello World!

import SchemaBuilder from '@pothos/core';
import EffectPlugin from 'pothos-plugin-effect';
import { Effect, Random } from 'effect';

const builder = new SchemaBuilder({
  plugins: [EffectPlugin],
});

builder.queryFields(t => ({
  roll: t.effect({
    type: 'Int',
    resolve() {
      // $ExpectType Effect.Effect<never, never, number>
      return Random.nextIntBetween(1, 6);
    },
  }),
}));

Documentations

Acknowledges

  • Pothos by @hayes (GitHub/Docs) - A nice GraphQL Schema builder. I heavily relied on the README for this project and The documentation of the plugin implementation is excellent.
  • Effect (GitHub/Docs)

Contributors

Made with contrib.rocks.

Licenses

MIT

pothos-plugin-effect's People

Contributors

hayes-mysten avatar iamchanii avatar vecerek avatar xiniha avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

xiniha vecerek hayes

pothos-plugin-effect's Issues

`@Effect/schema` integration

Hi there, great work on the integration so far!

I'm wondering if it would ever be possible to use @Effect/schema to specify the args to a query/mutation?

Perhaps by hooking into the validation plugin?

I know there is already some basic validation when parsing to/from graphql (string, number, null, array, etc. are checked), but it would be great to leverage @Effect/schema.

Add `useDefaultRuntime` options

In the future, this plugin will be make a Effect runtime, uses it in field resolver for isolated effect runtime environment. but I think there should be want to use default effect runtime (Effect.defaultRuntime). so I decided provide this option to opt out

Q: How does one `setConfigProvider` globally?

When one has an Effect, they can change the default config provider like so:

Effect.succeed(42),
Effect.provideLayer(Effect.setConfigProvider(ConfigProvider.fromMap(new Map([["key", "value"]]))))

However, I don't see how I can do this in the context of this plugin. If I add it to the effect resolver, it messes up my types because all the layers need to be provided before I can set a new config provider. I cannot do it in the effect.layers option either for a similar reason, and when I add that to the globalLayer effect options like so:

effectOptions: {
  globalLayer: Layer.provide(
    Effect.setConfigProvider(ConfigProvider.fromMap(new Map([["key", "value"]]))),
    Layer.context()
  ),
},

it type checks but does not seem to work at all. @iamchanii any idea how to configure your own config provider when using this plugin? ๐Ÿ™

Peerdeps has invalid ranges for Effect-TS packages

Since the Effect-TS packages are currently at 0.x version, minor version bumps can break the interface.
And it's actually happening right now (the latest version of @effect/io provides a new interface for Effect.Do and it's breaking the plugin since the plugin is expecting the old interface)
I'd suggest you lock down the minor version of Effect-TS peer dependencies, rather than marking every 0.x version as usable.

Improve prisma integration

  • Add prisma generator
generator effect {
  provider = "..."
}
  • Provide generated context
declare const Prisma: Context.Tag<EffectPrisma>;

// $ExpectType Effect.Effect<never, PrismaError, User>
Prisma.user.findUniqueOrThrow({ ... })
  • Provide PothosEffectPrismaClient tag
  • #25
  • I think ts-morph is too heavy. should I replace it to typescript?

Integration with the relay plugin

Hi there ๐Ÿ‘‹ I'm just about to start using Effect in one of my existing projects and would love to try your plugin. One thing I noticed during the migration was that there's a missing integration with the relay plugin that I use for declaring mutations like so:

builder.relayMutationField(
  "resourceCreate",
  {
    inputFields: (t) => ({
      a: t.string(),
    }),
  },
  {
    errors: {
      directResult: true,
      types: [
        FeatureUnavailableError,
        ForbiddenError,
        InvalidInputError,
        LimitReachedError,
      ],
    },
    resolve: async (_root, _args, _env) => ({
      resource: { /* blah blah blah */ },
    }),
  },
  {
    outputFields: (t) => ({
      resource: t.expose("resource", {
        nullable: false,
        type: "Resource",
      }),
    }),
  }
);

How would I write this mutation using the effect plugin?

Bug: type of the error failure is not preserved

When the failure/left type is an instance of an Error class, the original type of the error is not preserved. The plugin wraps the error cause in a new Error class.

Steps to reproduce

import SchemaBuilder from '@pothos/core';
import { Effect } from 'effect';
import { execute, parse } from 'graphql';
import EffectPlugin from 'pothos-plugin-effect';

interface SchemaTypes {
  Context: {
    diceResult: number;
  };
}

const builder = new SchemaBuilder<SchemaTypes>({
  plugins: [EffectPlugin],
  relayOptions: {},
});

class CustomError extends Error {
  readonly _tag = 'CustomError';
}

builder.queryField('roll', t =>
  t.effect({
    // @ts-expect-error
    resolve() {
      return Effect.fail(new CustomError("Boom!"));
    },
    type: ['Int'],
  })
);

const schema = builder.toSchema();
const document = parse(`{ roll }`);

execute({ document, schema }).then(console.log, console.error);

Expected behavior

The pothos-plugin-effect resolver throws an error of an instance of CustomError.

Actual behavior

The pothos-plugin-effect resolver wraps the CustomError in an instance of Error, or failErrorConstructor, or defaultFailErrorConstructor when so configured.

I think the current behavior is faulty mostly because the example code here suggests that the expected behavior described above should be the intended behavior, as well.

Motivation

I'm using the pothos-errors plugin, and I need the custom error class to be preserved for Pothos to be able to return the error as part of the expected error set in the data response.

CJS support

@iamchanii, I've just migrated one of my projects over to ESM just so I could consume this plugin. However, not all my projects are in a state where such migration is straightforward. Would you consider also exporting a CJS build of the library?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.