effect-orpc 0.1.4 → 0.2.1
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/README.md +95 -0
- package/dist/index.js +806 -476
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/contract.ts +491 -0
- package/src/effect-builder.ts +349 -619
- package/src/effect-enhance-router.ts +20 -21
- package/src/effect-procedure.ts +274 -263
- package/src/effect-runtime.ts +134 -0
- package/src/eoc.ts +499 -0
- package/src/extension/compose-surfaces.ts +15 -0
- package/src/extension/create-node-proxy.ts +270 -0
- package/src/extension/state.ts +108 -0
- package/src/index.ts +20 -3
- package/src/tagged-error.ts +24 -4
- package/src/tests/contract.test.ts +346 -0
- package/src/tests/effect-builder.proxy.test.ts +253 -0
- package/src/tests/effect-error-map.test.ts +22 -3
- package/src/tests/parity-shared.ts +32 -0
- package/src/tests/parity.contract-builder-variants.test.ts +192 -0
- package/src/tests/parity.contract-builder.test.ts +222 -0
- package/src/tests/parity.effect-builder.test.ts +210 -0
- package/src/tests/parity.effect-procedure.test.ts +124 -0
- package/src/tests/parity.implementer-variants.test.ts +249 -0
- package/src/tests/parity.implementer.test.ts +280 -0
- package/src/tests/shared.ts +2 -0
- package/src/types/effect-builder-surface.ts +441 -0
- package/src/types/effect-procedure-surface.ts +243 -0
- package/src/types/index.ts +22 -26
- package/src/types/variants.ts +100 -16
package/README.md
CHANGED
|
@@ -318,6 +318,55 @@ runtime-agnostic.
|
|
|
318
318
|
If you do not need framework-to-handler fiber propagation, you do not need the
|
|
319
319
|
`/node` entrypoint at all.
|
|
320
320
|
|
|
321
|
+
## Contract-First Usage
|
|
322
|
+
|
|
323
|
+
Use `implementEffect(contract, runtime)` when you already have an oRPC contract
|
|
324
|
+
and want to keep contract-first enforcement while adding Effect-native handlers.
|
|
325
|
+
Use `makeEffectORPC(runtime, builder?)` when you want to build procedures
|
|
326
|
+
directly from an oRPC builder.
|
|
327
|
+
|
|
328
|
+
```ts
|
|
329
|
+
import { Effect, ManagedRuntime } from "effect";
|
|
330
|
+
import { eoc, implementEffect } from "effect-orpc";
|
|
331
|
+
import z from "zod";
|
|
332
|
+
|
|
333
|
+
class UsersRepo extends Effect.Service<UsersRepo>()("UsersRepo", {
|
|
334
|
+
accessors: true,
|
|
335
|
+
sync: () => ({
|
|
336
|
+
list: (amount: number) =>
|
|
337
|
+
Array.from({ length: amount }, (_, index) => `user-${index + 1}`),
|
|
338
|
+
}),
|
|
339
|
+
}) {}
|
|
340
|
+
|
|
341
|
+
const contract = {
|
|
342
|
+
users: {
|
|
343
|
+
list: eoc
|
|
344
|
+
.input(z.object({ amount: z.number().int().positive() }))
|
|
345
|
+
.output(z.array(z.string())),
|
|
346
|
+
},
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
const runtime = ManagedRuntime.make(UsersRepo.Default);
|
|
350
|
+
const oe = implementEffect(contract, runtime);
|
|
351
|
+
|
|
352
|
+
export const router = oe.router({
|
|
353
|
+
users: {
|
|
354
|
+
list: oe.users.list.effect(function* ({ input }) {
|
|
355
|
+
return yield* UsersRepo.list(input.amount);
|
|
356
|
+
}),
|
|
357
|
+
},
|
|
358
|
+
});
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Contract leaves keep the contract-defined input, output, and error surface.
|
|
362
|
+
They add `.effect(...)` alongside existing implementer methods such as
|
|
363
|
+
`.handler(...)` and `.use(...)`, but do not expose contract-changing builder
|
|
364
|
+
methods like `.input(...)` or `.output(...)`.
|
|
365
|
+
|
|
366
|
+
If your contract declares tagged Effect error classes, prefer `eoc.errors(...)`
|
|
367
|
+
instead of raw `oc.errors(...)` so the error schema and metadata are derived
|
|
368
|
+
directly from the `ORPCTaggedError` class.
|
|
369
|
+
|
|
321
370
|
## API Reference
|
|
322
371
|
|
|
323
372
|
### `makeEffectORPC(runtime, builder?)`
|
|
@@ -337,6 +386,52 @@ const effectOs = makeEffectORPC(runtime);
|
|
|
337
386
|
const effectAuthedOs = makeEffectORPC(runtime, authedBuilder);
|
|
338
387
|
```
|
|
339
388
|
|
|
389
|
+
### `implementEffect(contract, runtime)`
|
|
390
|
+
|
|
391
|
+
Creates an Effect-aware contract implementer.
|
|
392
|
+
|
|
393
|
+
- `contract` - An oRPC contract router built with `oc`
|
|
394
|
+
- `runtime` - A `ManagedRuntime<R, E>` instance that provides services for Effect procedures
|
|
395
|
+
|
|
396
|
+
Returns a contract-shaped implementer tree whose leaves support `.effect(...)`.
|
|
397
|
+
|
|
398
|
+
```ts
|
|
399
|
+
const oe = implementEffect(contract, runtime);
|
|
400
|
+
|
|
401
|
+
const router = oe.router({
|
|
402
|
+
users: {
|
|
403
|
+
list: oe.users.list.effect(function* ({ input }) {
|
|
404
|
+
return yield* UsersRepo.list(input.amount);
|
|
405
|
+
}),
|
|
406
|
+
},
|
|
407
|
+
});
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### `eoc`
|
|
411
|
+
|
|
412
|
+
An Effect-aware wrapper around oRPC's `oc` contract builder.
|
|
413
|
+
|
|
414
|
+
Use it when you want contract definitions to accept `ORPCTaggedError` classes
|
|
415
|
+
directly in `.errors(...)` without duplicating the error schema.
|
|
416
|
+
|
|
417
|
+
```ts
|
|
418
|
+
class UserNotFoundError extends ORPCTaggedError("UserNotFoundError", {
|
|
419
|
+
code: "NOT_FOUND",
|
|
420
|
+
schema: z.object({ userId: z.string() }),
|
|
421
|
+
}) {}
|
|
422
|
+
|
|
423
|
+
const contract = {
|
|
424
|
+
users: {
|
|
425
|
+
find: eoc
|
|
426
|
+
.errors({
|
|
427
|
+
NOT_FOUND: UserNotFoundError,
|
|
428
|
+
})
|
|
429
|
+
.input(z.object({ userId: z.string() }))
|
|
430
|
+
.output(z.object({ userId: z.string() })),
|
|
431
|
+
},
|
|
432
|
+
};
|
|
433
|
+
```
|
|
434
|
+
|
|
340
435
|
### `EffectBuilder`
|
|
341
436
|
|
|
342
437
|
Wraps an oRPC Builder with Effect support. Available methods:
|