@teever/ez-hook-effect 0.4.4 → 0.5.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.
package/README.md CHANGED
@@ -25,17 +25,14 @@ npx jsr add @teever/ez-hook-effect
25
25
  ## Quick Start
26
26
 
27
27
  ```typescript
28
- import { Effect, Layer, pipe } from 'effect'
29
- import { sendWebhook, makeConfigLayer, HttpClientLive, WebhookServiceLive, Webhook } from '@teever/ez-hook-effect'
28
+ import { Effect, pipe } from 'effect'
29
+ import { makeDefaultLayer, sendWebhook, Webhook } from '@teever/ez-hook-effect'
30
30
 
31
31
  // Configure your webhook
32
32
  const WEBHOOK_URL = 'https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN'
33
33
 
34
- // Create service layers
35
- const AppLayer = WebhookServiceLive.pipe(
36
- Layer.provide(makeConfigLayer(WEBHOOK_URL)),
37
- Layer.provide(HttpClientLive)
38
- )
34
+ // Create service layer
35
+ const AppLayer = makeDefaultLayer(WEBHOOK_URL)
39
36
 
40
37
  // Send a simple message
41
38
  const program = pipe(
@@ -47,7 +44,7 @@ const program = pipe(
47
44
  )
48
45
 
49
46
  // Run the program
50
- Effect.runPromise(Effect.provide(program, AppLayer))
47
+ Effect.runPromise(program.pipe(Effect.provide(AppLayer)))
51
48
  ```
52
49
 
53
50
  ### Pipe-First API (Recommended)
@@ -105,7 +102,7 @@ const embedProgram = pipe(
105
102
 
106
103
  ## Error Handling
107
104
 
108
- Retries for rate limits (429) and transient errors (5xx) are handled automatically using configurable exponential backoff. You only need to handle errors that persist after retries are exhausted:
105
+ Retries for rate limits (429) and transient errors (5xx) are handled automatically using configurable exponential backoff. `sendWebhook` fails the Effect on any non-204 response, so errors always surface to your error handling paths.
109
106
 
110
107
  ```typescript
111
108
  import { Effect, pipe } from 'effect'
@@ -144,6 +141,54 @@ Effect.catchTag('ValidationError', (error) =>
144
141
  )
145
142
  ```
146
143
 
144
+ ### Error Helpers
145
+
146
+ ```typescript
147
+ import { Effect, pipe } from 'effect'
148
+ import { Webhook, sendWebhook, formatWebhookError, webhookErrorToLogObject } from '@teever/ez-hook-effect'
149
+
150
+ const program = pipe(
151
+ Webhook.make,
152
+ Webhook.setContent('Hello!'),
153
+ Webhook.build,
154
+ Effect.flatMap(sendWebhook),
155
+ Effect.catchAll((error) =>
156
+ Effect.logError(formatWebhookError(error)).pipe(
157
+ Effect.tap(() => Effect.log(JSON.stringify(webhookErrorToLogObject(error))))
158
+ )
159
+ )
160
+ )
161
+ ```
162
+
163
+ ## Raw Response
164
+
165
+ When you need status/body, use `sendWebhookRaw`:
166
+
167
+ ```typescript
168
+ import { Effect, pipe } from 'effect'
169
+ import { sendWebhookRaw, Webhook } from '@teever/ez-hook-effect'
170
+
171
+ const program = pipe(
172
+ Webhook.make,
173
+ Webhook.setContent('Hello!'),
174
+ Webhook.build,
175
+ Effect.flatMap(sendWebhookRaw),
176
+ Effect.tap((res) => Effect.log(`Status: ${res.status}`))
177
+ )
178
+ ```
179
+
180
+ ## Validate Only
181
+
182
+ ```typescript
183
+ import { Effect, pipe } from 'effect'
184
+ import { Webhook } from '@teever/ez-hook-effect'
185
+
186
+ const program = pipe(
187
+ Webhook.validate({ content: 'Hello!' }),
188
+ Effect.tap(() => Effect.log('Valid payload'))
189
+ )
190
+ ```
191
+
147
192
  ## Configuration Options
148
193
 
149
194
  ### Programmatic Configuration
@@ -160,6 +205,17 @@ const AppLayer = WebhookServiceLive.pipe(
160
205
  )
161
206
  ```
162
207
 
208
+ ### One-Liner Configuration
209
+
210
+ ```typescript
211
+ import { makeDefaultLayer } from '@teever/ez-hook-effect'
212
+
213
+ const AppLayer = makeDefaultLayer(WEBHOOK_URL, {
214
+ maxRetries: 5,
215
+ baseDelayMs: 1000,
216
+ })
217
+ ```
218
+
163
219
  ### Environment Variables
164
220
 
165
221
  ```typescript
@@ -198,7 +254,7 @@ Beyond sending messages, the library supports full webhook CRUD:
198
254
 
199
255
  ```typescript
200
256
  import { Effect, Layer, pipe } from 'effect'
201
- import { getWebhook, modifyWebhook, deleteWebhook, validateWebhook, WebhookServiceLive, makeConfigLayer, HttpClientLive } from '@teever/ez-hook-effect'
257
+ import { getWebhook, modifyWebhook, deleteWebhook, validateWebhook, WebhookService, WebhookServiceLive, makeConfigLayer, HttpClientLive } from '@teever/ez-hook-effect'
202
258
 
203
259
  const AppLayer = WebhookServiceLive.pipe(
204
260
  Layer.provide(makeConfigLayer(WEBHOOK_URL)),
@@ -226,6 +282,28 @@ const program = Effect.gen(function* () {
226
282
  Effect.runPromise(Effect.provide(program, AppLayer))
227
283
  ```
228
284
 
285
+ ## Testing Utilities
286
+
287
+ ```typescript
288
+ import { Effect, Layer, pipe } from 'effect'
289
+ import { makeTestHttpClient, WebhookServiceLive, makeConfigLayer } from '@teever/ez-hook-effect'
290
+
291
+ const TestHttpClient = makeTestHttpClient((_req) =>
292
+ Effect.succeed({
293
+ status: 204,
294
+ statusText: 'No Content',
295
+ headers: {},
296
+ body: null,
297
+ text: '',
298
+ })
299
+ )
300
+
301
+ const AppLayer = WebhookServiceLive.pipe(
302
+ Layer.provide(makeConfigLayer('https://discord.com/api/webhooks/123/abc')),
303
+ Layer.provide(TestHttpClient)
304
+ )
305
+ ```
306
+
229
307
  ## Development
230
308
 
231
309
  ```bash