effect 4.0.0-beta.104 → 4.0.0-beta.105
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/AGENTS.md +381 -0
- package/CLAUDE.md +381 -0
- package/ai-docs/README.md +44 -0
- package/ai-docs/package.json +36 -0
- package/ai-docs/src/01_effect/01_basics/01_effect-gen.ts +30 -0
- package/ai-docs/src/01_effect/01_basics/02_effect-fn.ts +39 -0
- package/ai-docs/src/01_effect/01_basics/10_creating-effects.ts +74 -0
- package/ai-docs/src/01_effect/01_basics/index.md +5 -0
- package/ai-docs/src/01_effect/02_schema/10_schema-basics.ts +43 -0
- package/ai-docs/src/01_effect/02_schema/index.md +7 -0
- package/ai-docs/src/01_effect/03_services/01_service.ts +45 -0
- package/ai-docs/src/01_effect/03_services/10_reference.ts +10 -0
- package/ai-docs/src/01_effect/03_services/20_layer-composition.ts +70 -0
- package/ai-docs/src/01_effect/03_services/20_layer-unwrap.ts +66 -0
- package/ai-docs/src/01_effect/03_services/index.md +5 -0
- package/ai-docs/src/01_effect/04_errors/01_error-handling.ts +30 -0
- package/ai-docs/src/01_effect/04_errors/10_catch-tags.ts +24 -0
- package/ai-docs/src/01_effect/04_errors/20_reason-errors.ts +64 -0
- package/ai-docs/src/01_effect/04_errors/index.md +1 -0
- package/ai-docs/src/01_effect/05_resources/10_acquire-release.ts +105 -0
- package/ai-docs/src/01_effect/05_resources/20_layer-side-effects.ts +31 -0
- package/ai-docs/src/01_effect/05_resources/30_layer-map.ts +86 -0
- package/ai-docs/src/01_effect/05_resources/index.md +3 -0
- package/ai-docs/src/01_effect/06_running/10_run-main.ts +30 -0
- package/ai-docs/src/01_effect/06_running/20_layer-launch.ts +27 -0
- package/ai-docs/src/01_effect/06_running/index.md +1 -0
- package/ai-docs/src/01_effect/07_pubsub/10_pubsub.ts +56 -0
- package/ai-docs/src/01_effect/07_pubsub/index.md +3 -0
- package/ai-docs/src/03_stream/10_creating-streams.ts +103 -0
- package/ai-docs/src/03_stream/20_consuming-streams.ts +137 -0
- package/ai-docs/src/03_stream/30_encoding.ts +165 -0
- package/ai-docs/src/03_stream/index.md +4 -0
- package/ai-docs/src/04_integration/10_managed-runtime.ts +129 -0
- package/ai-docs/src/04_integration/index.md +5 -0
- package/ai-docs/src/05_batching/10_request-resolver.ts +89 -0
- package/ai-docs/src/05_batching/index.md +3 -0
- package/ai-docs/src/06_schedule/10_schedules.ts +110 -0
- package/ai-docs/src/06_schedule/index.md +3 -0
- package/ai-docs/src/07_datetime/10_creating-and-formatting.ts +30 -0
- package/ai-docs/src/07_datetime/20_time-zones.ts +44 -0
- package/ai-docs/src/07_datetime/index.md +5 -0
- package/ai-docs/src/08_observability/10_logging.ts +66 -0
- package/ai-docs/src/08_observability/20_otlp-tracing.ts +95 -0
- package/ai-docs/src/08_observability/index.md +7 -0
- package/ai-docs/src/09_testing/10_effect-tests.ts +55 -0
- package/ai-docs/src/09_testing/20_layer-tests.ts +138 -0
- package/ai-docs/src/09_testing/index.md +1 -0
- package/ai-docs/src/10_predicate/01_basics.ts +14 -0
- package/ai-docs/src/10_predicate/index.md +9 -0
- package/ai-docs/src/50_http-client/10_basics.ts +102 -0
- package/ai-docs/src/50_http-client/index.md +3 -0
- package/ai-docs/src/51_http-server/10_basics.ts +116 -0
- package/ai-docs/src/51_http-server/fixtures/api/Api.ts +14 -0
- package/ai-docs/src/51_http-server/fixtures/api/Authorization.ts +36 -0
- package/ai-docs/src/51_http-server/fixtures/api/System.ts +10 -0
- package/ai-docs/src/51_http-server/fixtures/api/Users.ts +91 -0
- package/ai-docs/src/51_http-server/fixtures/domain/User.ts +12 -0
- package/ai-docs/src/51_http-server/fixtures/domain/UserErrors.ts +22 -0
- package/ai-docs/src/51_http-server/fixtures/server/Authorization.ts +36 -0
- package/ai-docs/src/51_http-server/fixtures/server/Users/http.ts +71 -0
- package/ai-docs/src/51_http-server/fixtures/server/Users.ts +62 -0
- package/ai-docs/src/51_http-server/index.md +3 -0
- package/ai-docs/src/60_child-process/10_working-with-child-processes.ts +117 -0
- package/ai-docs/src/60_child-process/index.md +3 -0
- package/ai-docs/src/70_cli/10_basics.ts +136 -0
- package/ai-docs/src/70_cli/index.md +5 -0
- package/ai-docs/src/71_ai/10_language-model.ts +156 -0
- package/ai-docs/src/71_ai/20_tools.ts +226 -0
- package/ai-docs/src/71_ai/30_chat.ts +158 -0
- package/ai-docs/src/71_ai/fixtures/domain/LaunchPlan.ts +9 -0
- package/ai-docs/src/71_ai/index.md +5 -0
- package/ai-docs/src/80_cluster/10_entities.ts +97 -0
- package/ai-docs/src/80_cluster/index.md +4 -0
- package/ai-docs/src/index.md +10 -0
- package/ai-docs/tsconfig.json +24 -0
- package/dist/Brand.d.ts +3 -3
- package/dist/Brand.d.ts.map +1 -1
- package/dist/Brand.js +4 -3
- package/dist/Brand.js.map +1 -1
- package/dist/Config.d.ts.map +1 -1
- package/dist/Config.js +2 -1
- package/dist/Config.js.map +1 -1
- package/dist/Context.d.ts +0 -1
- package/dist/Context.d.ts.map +1 -1
- package/dist/Context.js +1 -22
- package/dist/Context.js.map +1 -1
- package/dist/Cron.d.ts +31 -0
- package/dist/Cron.d.ts.map +1 -1
- package/dist/Cron.js +58 -2
- package/dist/Cron.js.map +1 -1
- package/dist/Optic.d.ts +35 -21
- package/dist/Optic.d.ts.map +1 -1
- package/dist/Optic.js +33 -34
- package/dist/Optic.js.map +1 -1
- package/dist/Schema.d.ts +73 -25
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +83 -50
- package/dist/Schema.js.map +1 -1
- package/dist/SchemaAST.d.ts +30 -0
- package/dist/SchemaAST.d.ts.map +1 -1
- package/dist/SchemaAST.js +40 -32
- package/dist/SchemaAST.js.map +1 -1
- package/dist/SchemaError.d.ts +8 -8
- package/dist/SchemaError.d.ts.map +1 -1
- package/dist/SchemaError.js +7 -6
- package/dist/SchemaError.js.map +1 -1
- package/dist/SchemaGetter.d.ts +8 -5
- package/dist/SchemaGetter.d.ts.map +1 -1
- package/dist/SchemaGetter.js +41 -37
- package/dist/SchemaGetter.js.map +1 -1
- package/dist/SchemaIssue.d.ts +195 -38
- package/dist/SchemaIssue.d.ts.map +1 -1
- package/dist/SchemaIssue.js +243 -68
- package/dist/SchemaIssue.js.map +1 -1
- package/dist/SchemaParser.d.ts +30 -0
- package/dist/SchemaParser.d.ts.map +1 -1
- package/dist/SchemaParser.js +39 -9
- package/dist/SchemaParser.js.map +1 -1
- package/dist/SchemaTransformation.d.ts +2 -2
- package/dist/SchemaTransformation.d.ts.map +1 -1
- package/dist/SchemaTransformation.js +26 -26
- package/dist/SchemaTransformation.js.map +1 -1
- package/dist/Stdio.d.ts +17 -4
- package/dist/Stdio.d.ts.map +1 -1
- package/dist/Stdio.js +6 -3
- package/dist/Stdio.js.map +1 -1
- package/dist/internal/schema/schema.js +1 -9
- package/dist/internal/schema/schema.js.map +1 -1
- package/dist/testing/TestSchema.d.ts +1 -1
- package/dist/testing/TestSchema.d.ts.map +1 -1
- package/dist/testing/TestSchema.js +8 -7
- package/dist/testing/TestSchema.js.map +1 -1
- package/dist/unstable/ai/Prompt.d.ts.map +1 -1
- package/dist/unstable/ai/Prompt.js +4 -4
- package/dist/unstable/ai/Prompt.js.map +1 -1
- package/dist/unstable/cluster/Reply.js +4 -4
- package/dist/unstable/cluster/Reply.js.map +1 -1
- package/dist/unstable/encoding/Msgpack.d.ts.map +1 -1
- package/dist/unstable/encoding/Msgpack.js +6 -6
- package/dist/unstable/encoding/Msgpack.js.map +1 -1
- package/dist/unstable/http/HttpClient.d.ts +59 -3
- package/dist/unstable/http/HttpClient.d.ts.map +1 -1
- package/dist/unstable/http/HttpClient.js +33 -19
- package/dist/unstable/http/HttpClient.js.map +1 -1
- package/dist/unstable/httpapi/HttpApiBuilder.js +10 -10
- package/dist/unstable/httpapi/HttpApiBuilder.js.map +1 -1
- package/dist/unstable/httpapi/HttpApiClient.js +9 -9
- package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
- package/dist/unstable/reactivity/AsyncResult.d.ts.map +1 -1
- package/dist/unstable/reactivity/AsyncResult.js +4 -4
- package/dist/unstable/reactivity/AsyncResult.js.map +1 -1
- package/dist/unstable/reactivity/Atom.d.ts +26 -11
- package/dist/unstable/reactivity/Atom.d.ts.map +1 -1
- package/dist/unstable/reactivity/Atom.js +9 -22
- package/dist/unstable/reactivity/Atom.js.map +1 -1
- package/dist/unstable/rpc/RpcClient.d.ts.map +1 -1
- package/dist/unstable/rpc/RpcClient.js +3 -1
- package/dist/unstable/rpc/RpcClient.js.map +1 -1
- package/dist/unstable/rpc/RpcServer.d.ts.map +1 -1
- package/dist/unstable/rpc/RpcServer.js +3 -2
- package/dist/unstable/rpc/RpcServer.js.map +1 -1
- package/dist/unstable/workflow/Workflow.d.ts.map +1 -1
- package/dist/unstable/workflow/Workflow.js +2 -2
- package/dist/unstable/workflow/Workflow.js.map +1 -1
- package/package.json +5 -2
- package/src/Brand.ts +4 -4
- package/src/Config.ts +3 -1
- package/src/Context.ts +1 -23
- package/src/Cron.ts +65 -2
- package/src/Optic.ts +59 -58
- package/src/Schema.ts +145 -71
- package/src/SchemaAST.ts +85 -48
- package/src/SchemaError.ts +9 -9
- package/src/SchemaGetter.ts +89 -30
- package/src/SchemaIssue.ts +285 -80
- package/src/SchemaParser.ts +51 -17
- package/src/SchemaTransformation.ts +66 -18
- package/src/Stdio.ts +23 -4
- package/src/internal/schema/schema.ts +1 -17
- package/src/testing/TestSchema.ts +8 -8
- package/src/unstable/ai/Prompt.ts +14 -4
- package/src/unstable/cluster/Reply.ts +4 -4
- package/src/unstable/encoding/Msgpack.ts +12 -8
- package/src/unstable/http/HttpClient.ts +132 -23
- package/src/unstable/httpapi/HttpApiBuilder.ts +32 -13
- package/src/unstable/httpapi/HttpApiClient.ts +26 -8
- package/src/unstable/reactivity/AsyncResult.ts +11 -6
- package/src/unstable/reactivity/Atom.ts +44 -25
- package/src/unstable/rpc/RpcClient.ts +4 -1
- package/src/unstable/rpc/RpcServer.ts +4 -2
- package/src/unstable/workflow/Workflow.ts +2 -5
|
@@ -1267,7 +1267,8 @@ export declare namespace WithRateLimiter {
|
|
|
1267
1267
|
*
|
|
1268
1268
|
* **Details**
|
|
1269
1269
|
*
|
|
1270
|
-
* They define the backing limiter, initial limit window, keying strategy,
|
|
1270
|
+
* They define the backing limiter, initial limit window, keying strategy,
|
|
1271
|
+
* algorithm, token cost, retry count, and response header inspection.
|
|
1271
1272
|
*
|
|
1272
1273
|
* @category rate limiting
|
|
1273
1274
|
* @since 4.0.0
|
|
@@ -1300,11 +1301,48 @@ export declare namespace WithRateLimiter {
|
|
|
1300
1301
|
*/
|
|
1301
1302
|
readonly tokens?: number | ((request: HttpClientRequest.HttpClientRequest) => number) | undefined
|
|
1302
1303
|
/**
|
|
1303
|
-
*
|
|
1304
|
+
* The maximum number of automatic retries after an HTTP `429` response.
|
|
1305
|
+
* Use a non-negative integer. Defaults to an unlimited number of retries.
|
|
1306
|
+
* Set to `0` to disable automatic retries.
|
|
1307
|
+
*/
|
|
1308
|
+
readonly times?: number | undefined
|
|
1309
|
+
/**
|
|
1310
|
+
* Overrides the response header names used for rate limit inspection.
|
|
1311
|
+
* Header names are matched case-insensitively. An omitted field continues
|
|
1312
|
+
* using the built-in names, while a configured field replaces them for
|
|
1313
|
+
* that value. Header value formats are unchanged.
|
|
1314
|
+
*/
|
|
1315
|
+
readonly responseHeaders?: {
|
|
1316
|
+
/**
|
|
1317
|
+
* Header containing the maximum number of requests in a window.
|
|
1318
|
+
*/
|
|
1319
|
+
readonly limit?: string | undefined
|
|
1320
|
+
/**
|
|
1321
|
+
* Header containing the number of requests remaining in a window.
|
|
1322
|
+
*/
|
|
1323
|
+
readonly remaining?: string | undefined
|
|
1324
|
+
/**
|
|
1325
|
+
* Header containing the rate limit reset time.
|
|
1326
|
+
*/
|
|
1327
|
+
readonly reset?: string | undefined
|
|
1328
|
+
/**
|
|
1329
|
+
* Header containing the number of seconds until the rate limit resets.
|
|
1330
|
+
*/
|
|
1331
|
+
readonly resetAfter?: string | undefined
|
|
1332
|
+
/**
|
|
1333
|
+
* Header containing the retry delay for an HTTP `429` response.
|
|
1334
|
+
*/
|
|
1335
|
+
readonly retryAfter?: string | undefined
|
|
1336
|
+
} | undefined
|
|
1337
|
+
/**
|
|
1338
|
+
* Disables automatic limit updates, `Retry-After` delays, and adaptive
|
|
1339
|
+
* feedback from response headers. This does not disable automatic HTTP
|
|
1340
|
+
* `429` retries. Set `times` to `0` to disable them.
|
|
1304
1341
|
*/
|
|
1305
1342
|
readonly disableResponseInspection?: boolean | undefined
|
|
1306
1343
|
/**
|
|
1307
|
-
*
|
|
1344
|
+
* Disables adaptive learning from `Retry-After` responses. Response
|
|
1345
|
+
* inspection and direct `Retry-After` delays remain enabled.
|
|
1308
1346
|
*/
|
|
1309
1347
|
readonly disableAdaptiveLearning?: boolean | undefined
|
|
1310
1348
|
}
|
|
@@ -1319,6 +1357,12 @@ export declare namespace WithRateLimiter {
|
|
|
1319
1357
|
* automatically retries HTTP `429` responses (or `HttpClientError` values
|
|
1320
1358
|
* wrapping a `429` response) by forcing the retry back through the limiter.
|
|
1321
1359
|
*
|
|
1360
|
+
* **Gotchas**
|
|
1361
|
+
*
|
|
1362
|
+
* Automatic HTTP `429` retries are unlimited unless `times` is specified.
|
|
1363
|
+
* Disabling response inspection does not disable retries; set `times` to `0`
|
|
1364
|
+
* to return or fail with the first `429`.
|
|
1365
|
+
*
|
|
1322
1366
|
* @category rate limiting
|
|
1323
1367
|
* @since 4.0.0
|
|
1324
1368
|
*/
|
|
@@ -1332,6 +1376,12 @@ export const withRateLimiter: {
|
|
|
1332
1376
|
* automatically retries HTTP `429` responses (or `HttpClientError` values
|
|
1333
1377
|
* wrapping a `429` response) by forcing the retry back through the limiter.
|
|
1334
1378
|
*
|
|
1379
|
+
* **Gotchas**
|
|
1380
|
+
*
|
|
1381
|
+
* Automatic HTTP `429` retries are unlimited unless `times` is specified.
|
|
1382
|
+
* Disabling response inspection does not disable retries; set `times` to `0`
|
|
1383
|
+
* to return or fail with the first `429`.
|
|
1384
|
+
*
|
|
1335
1385
|
* @category rate limiting
|
|
1336
1386
|
* @since 4.0.0
|
|
1337
1387
|
*/
|
|
@@ -1347,6 +1397,12 @@ export const withRateLimiter: {
|
|
|
1347
1397
|
* automatically retries HTTP `429` responses (or `HttpClientError` values
|
|
1348
1398
|
* wrapping a `429` response) by forcing the retry back through the limiter.
|
|
1349
1399
|
*
|
|
1400
|
+
* **Gotchas**
|
|
1401
|
+
*
|
|
1402
|
+
* Automatic HTTP `429` retries are unlimited unless `times` is specified.
|
|
1403
|
+
* Disabling response inspection does not disable retries; set `times` to `0`
|
|
1404
|
+
* to return or fail with the first `429`.
|
|
1405
|
+
*
|
|
1350
1406
|
* @category rate limiting
|
|
1351
1407
|
* @since 4.0.0
|
|
1352
1408
|
*/
|
|
@@ -1371,6 +1427,7 @@ export const withRateLimiter: {
|
|
|
1371
1427
|
? tokensOption
|
|
1372
1428
|
: constant(tokensOption ?? 1)
|
|
1373
1429
|
const adaptiveLearningEnabled = !options.disableAdaptiveLearning
|
|
1430
|
+
const headerNames = resolveRateLimiterHeaderNames(options.responseHeaders)
|
|
1374
1431
|
|
|
1375
1432
|
const getState = (key: string): RateLimiterState => {
|
|
1376
1433
|
const current = states.get(key)
|
|
@@ -1385,13 +1442,13 @@ export const withRateLimiter: {
|
|
|
1385
1442
|
? undefined
|
|
1386
1443
|
: (clock: Clock, key: string, headers: Headers.Headers, tokens: number) => {
|
|
1387
1444
|
const current = getState(key)
|
|
1388
|
-
const next = parseRateLimiterState(current, clock, headers, tokens)
|
|
1445
|
+
const next = parseRateLimiterState(current, clock, headers, tokens, headerNames)
|
|
1389
1446
|
if (next.limit !== current.limit || !Duration.equals(next.window, current.window)) {
|
|
1390
1447
|
states.set(key, next)
|
|
1391
1448
|
}
|
|
1392
1449
|
}
|
|
1393
1450
|
|
|
1394
|
-
return transform(self, function loop(effect, request): Effect.Effect<
|
|
1451
|
+
return transform(self, function loop(effect, request, retries = 0): Effect.Effect<
|
|
1395
1452
|
HttpClientResponse.HttpClientResponse,
|
|
1396
1453
|
E | RateLimiter.RateLimiterError,
|
|
1397
1454
|
R
|
|
@@ -1401,11 +1458,11 @@ export const withRateLimiter: {
|
|
|
1401
1458
|
const key = resolveKey(request)
|
|
1402
1459
|
const tokens = Math.max(resolveTokens(request), 1)
|
|
1403
1460
|
const current = getState(key)
|
|
1461
|
+
const canRetry = options.times === undefined || retries < options.times
|
|
1404
1462
|
function retry(retryAfter: Duration.Duration | undefined) {
|
|
1405
|
-
if (options.disableResponseInspection) return loop(effect, request)
|
|
1406
1463
|
return retryAfter
|
|
1407
|
-
? Effect.flatMap(Effect.sleep(retryAfter), () => loop(effect, request))
|
|
1408
|
-
: loop(effect, request)
|
|
1464
|
+
? Effect.flatMap(Effect.sleep(retryAfter), () => loop(effect, request, retries + 1))
|
|
1465
|
+
: loop(effect, request, retries + 1)
|
|
1409
1466
|
}
|
|
1410
1467
|
const inspectResponse = (
|
|
1411
1468
|
response: HttpClientResponse.HttpClientResponse,
|
|
@@ -1422,12 +1479,18 @@ export const withRateLimiter: {
|
|
|
1422
1479
|
* automatically retries HTTP `429` responses (or `HttpClientError` values
|
|
1423
1480
|
* wrapping a `429` response) by forcing the retry back through the limiter.
|
|
1424
1481
|
*
|
|
1482
|
+
* **Gotchas**
|
|
1483
|
+
*
|
|
1484
|
+
* Automatic HTTP `429` retries are unlimited unless `times` is specified.
|
|
1485
|
+
* Disabling response inspection does not disable retries; set `times` to `0`
|
|
1486
|
+
* to return or fail with the first `429`.
|
|
1487
|
+
*
|
|
1425
1488
|
* @category rate limiting
|
|
1426
1489
|
* @since 4.0.0
|
|
1427
1490
|
*/
|
|
1428
1491
|
Duration.Duration | undefined>(undefined);
|
|
1429
1492
|
}
|
|
1430
|
-
const retryAfter = parseRetryAfter(clock, getHeader(response.headers,
|
|
1493
|
+
const retryAfter = parseRetryAfter(clock, getHeader(response.headers, ...headerNames.retryAfter))
|
|
1431
1494
|
if (retryAfter === undefined) {
|
|
1432
1495
|
return Effect.succeed</**
|
|
1433
1496
|
* Applies request rate limiting using the `RateLimiter` service.
|
|
@@ -1438,12 +1501,18 @@ export const withRateLimiter: {
|
|
|
1438
1501
|
* automatically retries HTTP `429` responses (or `HttpClientError` values
|
|
1439
1502
|
* wrapping a `429` response) by forcing the retry back through the limiter.
|
|
1440
1503
|
*
|
|
1504
|
+
* **Gotchas**
|
|
1505
|
+
*
|
|
1506
|
+
* Automatic HTTP `429` retries are unlimited unless `times` is specified.
|
|
1507
|
+
* Disabling response inspection does not disable retries; set `times` to `0`
|
|
1508
|
+
* to return or fail with the first `429`.
|
|
1509
|
+
*
|
|
1441
1510
|
* @category rate limiting
|
|
1442
1511
|
* @since 4.0.0
|
|
1443
1512
|
*/
|
|
1444
1513
|
Duration.Duration | undefined>(undefined);
|
|
1445
1514
|
}
|
|
1446
|
-
const delay = parseRateLimitWindow(clock, response.headers) ?? retryAfter
|
|
1515
|
+
const delay = parseRateLimitWindow(clock, response.headers, headerNames) ?? retryAfter
|
|
1447
1516
|
if (adaptive === undefined) {
|
|
1448
1517
|
return Effect.succeed</**
|
|
1449
1518
|
* Applies request rate limiting using the `RateLimiter` service.
|
|
@@ -1454,6 +1523,12 @@ export const withRateLimiter: {
|
|
|
1454
1523
|
* automatically retries HTTP `429` responses (or `HttpClientError` values
|
|
1455
1524
|
* wrapping a `429` response) by forcing the retry back through the limiter.
|
|
1456
1525
|
*
|
|
1526
|
+
* **Gotchas**
|
|
1527
|
+
*
|
|
1528
|
+
* Automatic HTTP `429` retries are unlimited unless `times` is specified.
|
|
1529
|
+
* Disabling response inspection does not disable retries; set `times` to `0`
|
|
1530
|
+
* to return or fail with the first `429`.
|
|
1531
|
+
*
|
|
1457
1532
|
* @category rate limiting
|
|
1458
1533
|
* @since 4.0.0
|
|
1459
1534
|
*/
|
|
@@ -1489,7 +1564,7 @@ export const withRateLimiter: {
|
|
|
1489
1564
|
const request = Effect.matchEffect(effect, {
|
|
1490
1565
|
onSuccess(response) {
|
|
1491
1566
|
return Effect.flatMap(inspectResponse(response, adaptive), (retryAfter) => {
|
|
1492
|
-
if (response.status !== 429) return Effect.succeed(response)
|
|
1567
|
+
if (response.status !== 429 || !canRetry) return Effect.succeed(response)
|
|
1493
1568
|
return retry(retryAfter)
|
|
1494
1569
|
})
|
|
1495
1570
|
},
|
|
@@ -1497,7 +1572,7 @@ export const withRateLimiter: {
|
|
|
1497
1572
|
if (isTooManyRequestsHttpClientError(error)) {
|
|
1498
1573
|
return Effect.flatMap(
|
|
1499
1574
|
inspectResponse(error.reason.response, adaptive),
|
|
1500
|
-
(retryAfter) => retry(retryAfter)
|
|
1575
|
+
(retryAfter) => canRetry ? retry(retryAfter) : Effect.fail(error)
|
|
1501
1576
|
)
|
|
1502
1577
|
}
|
|
1503
1578
|
return Effect.fail(error)
|
|
@@ -1531,6 +1606,34 @@ export const withRateLimiter: {
|
|
|
1531
1606
|
});
|
|
1532
1607
|
})
|
|
1533
1608
|
|
|
1609
|
+
interface RateLimiterHeaderNames {
|
|
1610
|
+
readonly limit: ReadonlyArray<string>
|
|
1611
|
+
readonly remaining: ReadonlyArray<string>
|
|
1612
|
+
readonly reset: ReadonlyArray<string>
|
|
1613
|
+
readonly resetAfter: ReadonlyArray<string>
|
|
1614
|
+
readonly retryAfter: ReadonlyArray<string>
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
const resolveRateLimiterHeaderNames = (
|
|
1618
|
+
responseHeaders: WithRateLimiter.Options["responseHeaders"]
|
|
1619
|
+
): RateLimiterHeaderNames => ({
|
|
1620
|
+
limit: responseHeaders?.limit === undefined
|
|
1621
|
+
? ["ratelimit-limit", "x-ratelimit-limit"]
|
|
1622
|
+
: [responseHeaders.limit.toLowerCase()],
|
|
1623
|
+
remaining: responseHeaders?.remaining === undefined
|
|
1624
|
+
? ["ratelimit-remaining", "x-ratelimit-remaining"]
|
|
1625
|
+
: [responseHeaders.remaining.toLowerCase()],
|
|
1626
|
+
reset: responseHeaders?.reset === undefined
|
|
1627
|
+
? ["ratelimit-reset", "x-ratelimit-reset"]
|
|
1628
|
+
: [responseHeaders.reset.toLowerCase()],
|
|
1629
|
+
resetAfter: responseHeaders?.resetAfter === undefined
|
|
1630
|
+
? ["ratelimit-reset-after", "x-ratelimit-reset-after"]
|
|
1631
|
+
: [responseHeaders.resetAfter.toLowerCase()],
|
|
1632
|
+
retryAfter: responseHeaders?.retryAfter === undefined
|
|
1633
|
+
? ["retry-after"]
|
|
1634
|
+
: [responseHeaders.retryAfter.toLowerCase()]
|
|
1635
|
+
})
|
|
1636
|
+
|
|
1534
1637
|
interface RateLimiterState {
|
|
1535
1638
|
readonly limit: number
|
|
1536
1639
|
readonly window: Duration.Duration
|
|
@@ -1541,10 +1644,11 @@ const parseRateLimiterState = (
|
|
|
1541
1644
|
state: RateLimiterState,
|
|
1542
1645
|
clock: Clock,
|
|
1543
1646
|
headers: Headers.Headers,
|
|
1544
|
-
tokens: number
|
|
1647
|
+
tokens: number,
|
|
1648
|
+
headerNames: RateLimiterHeaderNames
|
|
1545
1649
|
): RateLimiterState => {
|
|
1546
|
-
const limit = parseRateLimitLimit(state, headers, tokens) ?? state.limit
|
|
1547
|
-
const window = parseRateLimitWindow(clock, headers) ?? state.window
|
|
1650
|
+
const limit = parseRateLimitLimit(state, headers, tokens, headerNames) ?? state.limit
|
|
1651
|
+
const window = parseRateLimitWindow(clock, headers, headerNames) ?? state.window
|
|
1548
1652
|
if (limit === state.limit && Duration.equals(window, state.window)) {
|
|
1549
1653
|
return state
|
|
1550
1654
|
}
|
|
@@ -1554,35 +1658,40 @@ const parseRateLimiterState = (
|
|
|
1554
1658
|
const parseRateLimitLimit = (
|
|
1555
1659
|
state: RateLimiterState,
|
|
1556
1660
|
headers: Headers.Headers,
|
|
1557
|
-
tokens: number
|
|
1661
|
+
tokens: number,
|
|
1662
|
+
headerNames: RateLimiterHeaderNames
|
|
1558
1663
|
): number | undefined => {
|
|
1559
|
-
const raw = getHeader(headers,
|
|
1664
|
+
const raw = getHeader(headers, ...headerNames.limit)
|
|
1560
1665
|
const value = parseNumberHeader(raw)
|
|
1561
1666
|
if (value !== undefined && value > 0) {
|
|
1562
1667
|
return value
|
|
1563
1668
|
}
|
|
1564
|
-
const remaining = parseRateLimitRemaining(headers)
|
|
1669
|
+
const remaining = parseRateLimitRemaining(headers, headerNames)
|
|
1565
1670
|
if (remaining === undefined) {
|
|
1566
1671
|
return undefined
|
|
1567
1672
|
}
|
|
1568
1673
|
return state.initial ? remaining + tokens : Math.max(remaining + tokens, state.limit)
|
|
1569
1674
|
}
|
|
1570
1675
|
|
|
1571
|
-
const parseRateLimitRemaining = (
|
|
1572
|
-
|
|
1676
|
+
const parseRateLimitRemaining = (
|
|
1677
|
+
headers: Headers.Headers,
|
|
1678
|
+
headerNames: RateLimiterHeaderNames
|
|
1679
|
+
): number | undefined => {
|
|
1680
|
+
const raw = getHeader(headers, ...headerNames.remaining)
|
|
1573
1681
|
const value = parseNumberHeader(raw)
|
|
1574
1682
|
return value !== undefined && value >= 0 ? value : undefined
|
|
1575
1683
|
}
|
|
1576
1684
|
|
|
1577
1685
|
const parseRateLimitWindow = (
|
|
1578
1686
|
clock: Clock,
|
|
1579
|
-
headers: Headers.Headers
|
|
1687
|
+
headers: Headers.Headers,
|
|
1688
|
+
headerNames: RateLimiterHeaderNames
|
|
1580
1689
|
): Duration.Duration | undefined => {
|
|
1581
|
-
const resetAfter = parseResetAfter(getHeader(headers,
|
|
1690
|
+
const resetAfter = parseResetAfter(getHeader(headers, ...headerNames.resetAfter))
|
|
1582
1691
|
if (resetAfter !== undefined) {
|
|
1583
1692
|
return resetAfter
|
|
1584
1693
|
}
|
|
1585
|
-
return parseResetHeader(clock, getHeader(headers,
|
|
1694
|
+
return parseResetHeader(clock, getHeader(headers, ...headerNames.reset))
|
|
1586
1695
|
}
|
|
1587
1696
|
|
|
1588
1697
|
const parseRetryAfter = (
|
|
@@ -1101,10 +1101,10 @@ function toResponseErrorSchema(
|
|
|
1101
1101
|
HttpApiSchema.isNoContent(schema.schema.ast)
|
|
1102
1102
|
)
|
|
1103
1103
|
const transformation = withHeadersTransformation<HttpApiSchema.withHeaders<unknown, Schema.StringTree>>(
|
|
1104
|
-
(body) =>
|
|
1105
|
-
encodeBody(body).pipe(
|
|
1104
|
+
(body, options) =>
|
|
1105
|
+
encodeBody(body, options).pipe(
|
|
1106
1106
|
Effect.mapError((error) => error.issue),
|
|
1107
|
-
Effect.flatMap(encodeResponse)
|
|
1107
|
+
Effect.flatMap((body) => encodeResponse(body, options))
|
|
1108
1108
|
),
|
|
1109
1109
|
encodeHeaders
|
|
1110
1110
|
)
|
|
@@ -1167,22 +1167,34 @@ function getResponseTransformation(
|
|
|
1167
1167
|
)
|
|
1168
1168
|
|
|
1169
1169
|
return SchemaTransformation.transformOrFail({
|
|
1170
|
-
decode: () =>
|
|
1170
|
+
decode: (input, options) =>
|
|
1171
|
+
Effect.fail(
|
|
1172
|
+
new SchemaIssue.Forbidden({ message: "Encode only schema" }, input, options)
|
|
1173
|
+
),
|
|
1171
1174
|
encode
|
|
1172
1175
|
})
|
|
1173
1176
|
}
|
|
1174
1177
|
|
|
1175
1178
|
function withHeadersTransformation<T = unknown>(
|
|
1176
|
-
encodeBody: (
|
|
1177
|
-
|
|
1179
|
+
encodeBody: (
|
|
1180
|
+
body: unknown,
|
|
1181
|
+
options?: SchemaAST.ParseOptions
|
|
1182
|
+
) => Effect.Effect<Response.HttpServerResponse, SchemaIssue.Issue, unknown>,
|
|
1183
|
+
encodeHeaders: (
|
|
1184
|
+
headers: unknown,
|
|
1185
|
+
options?: SchemaAST.ParseOptions
|
|
1186
|
+
) => Effect.Effect<unknown, Schema.SchemaError, unknown>
|
|
1178
1187
|
): SchemaTransformation.Transformation<T, Response.HttpServerResponse, never, unknown> {
|
|
1179
1188
|
return SchemaTransformation.transformOrFail<T, Response.HttpServerResponse, never, unknown>({
|
|
1180
|
-
decode: () =>
|
|
1181
|
-
|
|
1189
|
+
decode: (input, options) =>
|
|
1190
|
+
Effect.fail(
|
|
1191
|
+
new SchemaIssue.Forbidden({ message: "Encode only schema" }, input, options)
|
|
1192
|
+
),
|
|
1193
|
+
encode: (value, options) => {
|
|
1182
1194
|
const pair = value as { readonly body: unknown; readonly headers: unknown }
|
|
1183
|
-
return Effect.flatMap(encodeBody(pair.body), (response) =>
|
|
1195
|
+
return Effect.flatMap(encodeBody(pair.body, options), (response) =>
|
|
1184
1196
|
Effect.map(
|
|
1185
|
-
encodeHeaders(pair.headers).pipe(Effect.mapError((error) => error.issue)),
|
|
1197
|
+
encodeHeaders(pair.headers, options).pipe(Effect.mapError((error) => error.issue)),
|
|
1186
1198
|
(headers) => Response.setHeaders(response, headers as any)
|
|
1187
1199
|
))
|
|
1188
1200
|
}
|
|
@@ -1193,10 +1205,13 @@ function getResponseEncode<E>(
|
|
|
1193
1205
|
status: number,
|
|
1194
1206
|
encoding: HttpApiSchema.ResponseEncoding,
|
|
1195
1207
|
isNoContent: boolean
|
|
1196
|
-
): (
|
|
1208
|
+
): (
|
|
1209
|
+
e: E,
|
|
1210
|
+
options?: SchemaAST.ParseOptions
|
|
1211
|
+
) => Effect.Effect<Response.HttpServerResponse, SchemaIssue.InvalidValue, never> {
|
|
1197
1212
|
switch (encoding._tag) {
|
|
1198
1213
|
case "Json": {
|
|
1199
|
-
return ((e) => {
|
|
1214
|
+
return ((e, options) => {
|
|
1200
1215
|
if (e === undefined || isNoContent) {
|
|
1201
1216
|
return Effect.succeed(Response.empty({ status }))
|
|
1202
1217
|
}
|
|
@@ -1205,7 +1220,11 @@ function getResponseEncode<E>(
|
|
|
1205
1220
|
return Effect.succeed(Response.text(s, { status, contentType: encoding.contentType }))
|
|
1206
1221
|
} catch {
|
|
1207
1222
|
return Effect.fail(
|
|
1208
|
-
new SchemaIssue.InvalidValue(
|
|
1223
|
+
new SchemaIssue.InvalidValue(
|
|
1224
|
+
{ expected: "a JSON-serializable response body" },
|
|
1225
|
+
e,
|
|
1226
|
+
options
|
|
1227
|
+
)
|
|
1209
1228
|
)
|
|
1210
1229
|
}
|
|
1211
1230
|
})
|
|
@@ -1065,41 +1065,59 @@ function getEncodePayloadSchemaFromBody(
|
|
|
1065
1065
|
const out = $HttpBody.pipe(Schema.decodeTo(
|
|
1066
1066
|
schema,
|
|
1067
1067
|
SchemaTransformation.transformOrFail<unknown, HttpBody.HttpBody>({
|
|
1068
|
-
decode() {
|
|
1069
|
-
return Effect.fail(
|
|
1068
|
+
decode(input, options) {
|
|
1069
|
+
return Effect.fail(
|
|
1070
|
+
new SchemaIssue.Forbidden({ message: "Encode only schema" }, input, options)
|
|
1071
|
+
)
|
|
1070
1072
|
},
|
|
1071
|
-
encode(t) {
|
|
1073
|
+
encode(t, options) {
|
|
1072
1074
|
switch (encoding._tag) {
|
|
1073
1075
|
case "Multipart":
|
|
1074
|
-
return Effect.fail(
|
|
1076
|
+
return Effect.fail(
|
|
1077
|
+
new SchemaIssue.Forbidden(
|
|
1078
|
+
{ message: "Payload must be a FormData" },
|
|
1079
|
+
t,
|
|
1080
|
+
options
|
|
1081
|
+
)
|
|
1082
|
+
)
|
|
1075
1083
|
case "Json": {
|
|
1076
1084
|
try {
|
|
1077
1085
|
const body = JSON.stringify(t)
|
|
1078
1086
|
return Effect.succeed(HttpBody.text(body, encoding.contentType))
|
|
1079
1087
|
} catch {
|
|
1080
1088
|
return Effect.fail(
|
|
1081
|
-
new SchemaIssue.InvalidValue(
|
|
1089
|
+
new SchemaIssue.InvalidValue(
|
|
1090
|
+
{ expected: "a JSON-serializable request body" },
|
|
1091
|
+
t,
|
|
1092
|
+
options
|
|
1093
|
+
)
|
|
1082
1094
|
)
|
|
1083
1095
|
}
|
|
1084
1096
|
}
|
|
1085
1097
|
case "Text": {
|
|
1086
1098
|
if (typeof t !== "string") {
|
|
1087
1099
|
return Effect.fail(
|
|
1088
|
-
new SchemaIssue.InvalidValue({ message: "Expected a string" })
|
|
1100
|
+
new SchemaIssue.InvalidValue({ message: "Expected a string" }, t, options)
|
|
1089
1101
|
)
|
|
1090
1102
|
}
|
|
1091
1103
|
return Effect.succeed(HttpBody.text(t, encoding.contentType))
|
|
1092
1104
|
}
|
|
1093
1105
|
case "FormUrlEncoded": {
|
|
1094
1106
|
if (!Predicate.isObject(t)) {
|
|
1095
|
-
return Effect.fail(
|
|
1107
|
+
return Effect.fail(
|
|
1108
|
+
new SchemaIssue.InvalidValue({ message: "Expected a record" }, t, options)
|
|
1109
|
+
)
|
|
1096
1110
|
}
|
|
1097
1111
|
return Effect.succeed(HttpBody.urlParams(UrlParams.fromInput(t as any), encoding.contentType))
|
|
1098
1112
|
}
|
|
1099
1113
|
case "Uint8Array": {
|
|
1100
1114
|
if (!(t instanceof Uint8Array)) {
|
|
1101
1115
|
return Effect.fail(
|
|
1102
|
-
new SchemaIssue.InvalidValue(
|
|
1116
|
+
new SchemaIssue.InvalidValue(
|
|
1117
|
+
{ message: "Expected a Uint8Array" },
|
|
1118
|
+
t,
|
|
1119
|
+
options
|
|
1120
|
+
)
|
|
1103
1121
|
)
|
|
1104
1122
|
}
|
|
1105
1123
|
return Effect.succeed(HttpBody.uint8Array(t, encoding.contentType))
|
|
@@ -1101,7 +1101,7 @@ export const Schema = <
|
|
|
1101
1101
|
[success_, Schema_.Cause(error, Schema_.Defect())],
|
|
1102
1102
|
([value, cause]) => (input, ast, options) => {
|
|
1103
1103
|
if (!isAsyncResult(input)) {
|
|
1104
|
-
return Effect.fail(new SchemaIssue.InvalidType(ast))
|
|
1104
|
+
return Effect.fail(new SchemaIssue.InvalidType(ast, input, options))
|
|
1105
1105
|
}
|
|
1106
1106
|
switch (input._tag) {
|
|
1107
1107
|
case "Initial":
|
|
@@ -1111,7 +1111,7 @@ export const Schema = <
|
|
|
1111
1111
|
SchemaParser.decodeUnknownEffect(value)(input.value, options),
|
|
1112
1112
|
{
|
|
1113
1113
|
onSuccess: (value) => success(value, input),
|
|
1114
|
-
onFailure: (issue) =>
|
|
1114
|
+
onFailure: (issue) => SchemaIssue.makeCompositeAtKey(ast, "value", issue, input, options)
|
|
1115
1115
|
}
|
|
1116
1116
|
)
|
|
1117
1117
|
case "Failure": {
|
|
@@ -1122,9 +1122,14 @@ export const Schema = <
|
|
|
1122
1122
|
{
|
|
1123
1123
|
onSuccess: (value) => Option.some(success<A["Type"], E["Type"]>(value, ps)),
|
|
1124
1124
|
onFailure: (issue) =>
|
|
1125
|
-
new SchemaIssue.Composite(
|
|
1126
|
-
|
|
1127
|
-
|
|
1125
|
+
new SchemaIssue.Composite(
|
|
1126
|
+
ast,
|
|
1127
|
+
[
|
|
1128
|
+
new SchemaIssue.Pointer(["previousSuccess", "value"], issue)
|
|
1129
|
+
],
|
|
1130
|
+
input,
|
|
1131
|
+
options
|
|
1132
|
+
)
|
|
1128
1133
|
}
|
|
1129
1134
|
)
|
|
1130
1135
|
),
|
|
@@ -1132,7 +1137,7 @@ export const Schema = <
|
|
|
1132
1137
|
)
|
|
1133
1138
|
const causeEffect = Effect.mapErrorEager(
|
|
1134
1139
|
SchemaParser.decodeUnknownEffect(cause)(input.cause, options),
|
|
1135
|
-
(issue) =>
|
|
1140
|
+
(issue) => SchemaIssue.makeCompositeAtKey(ast, "cause", issue, input, options)
|
|
1136
1141
|
)
|
|
1137
1142
|
return Effect.flatMapEager(
|
|
1138
1143
|
prevSuccessEffect,
|
|
@@ -790,7 +790,7 @@ export interface AtomRuntime<R, ER = never> extends Atom<AsyncResult.AsyncResult
|
|
|
790
790
|
}
|
|
791
791
|
|
|
792
792
|
/**
|
|
793
|
-
* Factory for `AtomRuntime` values that share a
|
|
793
|
+
* Factory for `AtomRuntime` values that share a set of global layers.
|
|
794
794
|
*
|
|
795
795
|
* @category models
|
|
796
796
|
* @since 4.0.0
|
|
@@ -801,7 +801,6 @@ export interface RuntimeFactory {
|
|
|
801
801
|
| Layer.Layer<R, E, AtomRegistry | Reactivity.Reactivity>
|
|
802
802
|
| ((get: AtomContext) => Layer.Layer<R, E, AtomRegistry | Reactivity.Reactivity>)
|
|
803
803
|
): AtomRuntime<R, E>
|
|
804
|
-
readonly memoMap: Layer.MemoMap
|
|
805
804
|
readonly addGlobalLayer: <A, E>(layer: Layer.Layer<A, E, AtomRegistry | Reactivity.Reactivity>) => void
|
|
806
805
|
|
|
807
806
|
/**
|
|
@@ -814,14 +813,40 @@ export interface RuntimeFactory {
|
|
|
814
813
|
}
|
|
815
814
|
|
|
816
815
|
/**
|
|
817
|
-
*
|
|
816
|
+
* A `RuntimeFactory` backed by an atom whose memo map is scoped to each registry.
|
|
818
817
|
*
|
|
819
|
-
* @category
|
|
818
|
+
* @category models
|
|
820
819
|
* @since 4.0.0
|
|
821
820
|
*/
|
|
822
|
-
export
|
|
821
|
+
export interface RegistryRuntimeFactory extends RuntimeFactory {
|
|
822
|
+
readonly memoMap: Atom<Layer.MemoMap>
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
/**
|
|
826
|
+
* A `RuntimeFactory` backed by a concrete memo map shared across registries.
|
|
827
|
+
*
|
|
828
|
+
* @category models
|
|
829
|
+
* @since 4.0.0
|
|
830
|
+
*/
|
|
831
|
+
export interface SharedRuntimeFactory extends RuntimeFactory {
|
|
823
832
|
readonly memoMap: Layer.MemoMap
|
|
824
|
-
}
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
/**
|
|
836
|
+
* Creates a `RuntimeFactory` backed by a registry-scoped memo map by default,
|
|
837
|
+
* or by the supplied atom or concrete `Layer.MemoMap`.
|
|
838
|
+
*
|
|
839
|
+
* @category constructors
|
|
840
|
+
* @since 4.0.0
|
|
841
|
+
*/
|
|
842
|
+
export function context(): RegistryRuntimeFactory
|
|
843
|
+
export function context(options: { readonly memoMap: Atom<Layer.MemoMap> }): RegistryRuntimeFactory
|
|
844
|
+
export function context(options: { readonly memoMap: Layer.MemoMap }): SharedRuntimeFactory
|
|
845
|
+
export function context(options?: {
|
|
846
|
+
readonly memoMap: Atom<Layer.MemoMap> | Layer.MemoMap
|
|
847
|
+
}): RegistryRuntimeFactory | SharedRuntimeFactory {
|
|
848
|
+
const memoMap = options?.memoMap ?? removeTtl(make(() => Layer.makeMemoMapUnsafe()))
|
|
849
|
+
const resolveMemoMap = (get: AtomContext): Layer.MemoMap => isAtom(memoMap) ? get(memoMap) : memoMap
|
|
825
850
|
let globalLayer: Layer.Layer<any, any, AtomRegistry> = Reactivity.layer
|
|
826
851
|
function factory<E, R>(
|
|
827
852
|
create:
|
|
@@ -843,23 +868,25 @@ export const context: (options: {
|
|
|
843
868
|
|
|
844
869
|
self.read = function read(get: AtomContext) {
|
|
845
870
|
const layer = get(layerAtom)
|
|
846
|
-
const build = Effect.flatMap(Effect.scope, (scope) => Layer.buildWithMemoMap(layer,
|
|
871
|
+
const build = Effect.flatMap(Effect.scope, (scope) => Layer.buildWithMemoMap(layer, resolveMemoMap(get), scope))
|
|
847
872
|
return effect(get, build, { uninterruptible: true })
|
|
848
873
|
}
|
|
849
874
|
|
|
850
875
|
return self
|
|
851
876
|
}
|
|
852
|
-
factory.memoMap =
|
|
877
|
+
factory.memoMap = memoMap
|
|
853
878
|
factory.addGlobalLayer = (layer: Layer.Layer<any, any, AtomRegistry | Reactivity.Reactivity>) => {
|
|
854
879
|
globalLayer = Layer.provideMerge(globalLayer, Layer.provide(layer, Reactivity.layer))
|
|
855
880
|
}
|
|
856
|
-
const reactivityAtom = removeTtl(
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
881
|
+
const reactivityAtom = removeTtl(
|
|
882
|
+
make((get) =>
|
|
883
|
+
Effect.contextWith((services: Context.Context<Scope.Scope>) =>
|
|
884
|
+
Layer.buildWithMemoMap(Reactivity.layer, resolveMemoMap(get), Context.get(services, Scope.Scope))
|
|
885
|
+
).pipe(
|
|
886
|
+
Effect.map(Context.get(Reactivity.Reactivity))
|
|
887
|
+
)
|
|
861
888
|
)
|
|
862
|
-
)
|
|
889
|
+
)
|
|
863
890
|
factory.withReactivity =
|
|
864
891
|
(keys: ReadonlyArray<unknown> | ReadonlyRecord<string, ReadonlyArray<unknown>>) =>
|
|
865
892
|
<A extends Atom<any>>(atom: A): A =>
|
|
@@ -871,24 +898,16 @@ export const context: (options: {
|
|
|
871
898
|
get.subscribe(atom, (value) => get.setSelf(value))
|
|
872
899
|
return get.once(atom)
|
|
873
900
|
}, { initialValueTarget: atom }) as any as A
|
|
874
|
-
return factory
|
|
901
|
+
return factory as any
|
|
875
902
|
}
|
|
876
903
|
|
|
877
904
|
/**
|
|
878
|
-
* Default
|
|
879
|
-
*
|
|
880
|
-
* @category context
|
|
881
|
-
* @since 4.0.0
|
|
882
|
-
*/
|
|
883
|
-
export const defaultMemoMap: Layer.MemoMap = Layer.makeMemoMapUnsafe()
|
|
884
|
-
|
|
885
|
-
/**
|
|
886
|
-
* Default `RuntimeFactory` created with `defaultMemoMap`.
|
|
905
|
+
* Default registry-scoped `RuntimeFactory`.
|
|
887
906
|
*
|
|
888
907
|
* @category context
|
|
889
908
|
* @since 4.0.0
|
|
890
909
|
*/
|
|
891
|
-
export const runtime:
|
|
910
|
+
export const runtime: RegistryRuntimeFactory = context()
|
|
892
911
|
|
|
893
912
|
/**
|
|
894
913
|
* Returns `Rx.runtime.withReactivity` for refreshing an atom whenever the
|
|
@@ -23,6 +23,7 @@ import * as Latch from "../../Latch.ts"
|
|
|
23
23
|
import * as Layer from "../../Layer.ts"
|
|
24
24
|
import * as Option from "../../Option.ts"
|
|
25
25
|
import * as Pool from "../../Pool.ts"
|
|
26
|
+
import * as Predicate from "../../Predicate.ts"
|
|
26
27
|
import * as Queue from "../../Queue.ts"
|
|
27
28
|
import * as Result from "../../Result.ts"
|
|
28
29
|
import * as Schedule from "../../Schedule.ts"
|
|
@@ -51,6 +52,8 @@ import * as RpcSerialization from "./RpcSerialization.ts"
|
|
|
51
52
|
import * as RpcWorker from "./RpcWorker.ts"
|
|
52
53
|
import { withRunClient } from "./Utils.ts"
|
|
53
54
|
|
|
55
|
+
const isRpcClientError = (u: unknown): u is RpcClientError => Predicate.isTagged(u, "RpcClientError")
|
|
56
|
+
|
|
54
57
|
/**
|
|
55
58
|
* The object-shaped client generated from a union of RPC definitions, with one
|
|
56
59
|
* method per RPC tag.
|
|
@@ -974,7 +977,7 @@ export const makeProtocolHttp = (client: HttpClient.HttpClient): Effect.Effect<
|
|
|
974
977
|
})
|
|
975
978
|
})
|
|
976
979
|
)).pipe(
|
|
977
|
-
Effect.mapError((cause) => cause
|
|
980
|
+
Effect.mapError((cause) => isRpcClientError(cause) ? cause : httpClientError(cause))
|
|
978
981
|
)
|
|
979
982
|
if (!hasResponse) {
|
|
980
983
|
return yield* emptyResponseError(request)
|