@livestore/utils 0.4.0 → 0.5.0-dev.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/dist/.tsbuildinfo +1 -1
- package/dist/Deferred.d.ts.map +1 -1
- package/dist/NoopTracer.d.ts +7 -8
- package/dist/NoopTracer.d.ts.map +1 -1
- package/dist/NoopTracer.js +3 -18
- package/dist/NoopTracer.js.map +1 -1
- package/dist/NoopTracer.test.d.ts +2 -0
- package/dist/NoopTracer.test.d.ts.map +1 -0
- package/dist/NoopTracer.test.js +29 -0
- package/dist/NoopTracer.test.js.map +1 -0
- package/dist/base64.d.ts.map +1 -1
- package/dist/binary.d.ts.map +1 -1
- package/dist/browser/Opfs/Opfs.d.ts +179 -29
- package/dist/browser/Opfs/Opfs.d.ts.map +1 -1
- package/dist/browser/Opfs/Opfs.js +134 -309
- package/dist/browser/Opfs/Opfs.js.map +1 -1
- package/dist/browser/Opfs/debug-utils.d.ts.map +1 -1
- package/dist/browser/Opfs/debug-utils.js +6 -5
- package/dist/browser/Opfs/debug-utils.js.map +1 -1
- package/dist/browser/Opfs/mod.js +3 -3
- package/dist/browser/Opfs/utils.d.ts +8 -8
- package/dist/browser/Opfs/utils.d.ts.map +1 -1
- package/dist/browser/Opfs/utils.js +35 -26
- package/dist/browser/Opfs/utils.js.map +1 -1
- package/dist/browser/QuotaExceededError.d.ts +10 -9
- package/dist/browser/QuotaExceededError.d.ts.map +1 -1
- package/dist/browser/WebChannelBrowser.d.ts.map +1 -1
- package/dist/browser/WebChannelBrowser.js +25 -14
- package/dist/browser/WebChannelBrowser.js.map +1 -1
- package/dist/browser/WebError.d.ts +55 -87
- package/dist/browser/WebError.d.ts.map +1 -1
- package/dist/browser/WebError.js +92 -85
- package/dist/browser/WebError.js.map +1 -1
- package/dist/browser/WebError.test.js +7 -7
- package/dist/browser/WebError.test.js.map +1 -1
- package/dist/browser/WebLock.d.ts +1 -1
- package/dist/browser/WebLock.d.ts.map +1 -1
- package/dist/browser/WebLock.js +13 -13
- package/dist/browser/WebLock.js.map +1 -1
- package/dist/browser/mod.js +6 -6
- package/dist/cuid/cuid.browser.d.ts.map +1 -1
- package/dist/cuid/cuid.node.d.ts.map +1 -1
- package/dist/effect/Debug.d.ts +4 -7
- package/dist/effect/Debug.d.ts.map +1 -1
- package/dist/effect/Debug.js +34 -40
- package/dist/effect/Debug.js.map +1 -1
- package/dist/effect/Effect.d.ts +31 -22
- package/dist/effect/Effect.d.ts.map +1 -1
- package/dist/effect/Effect.js +54 -50
- package/dist/effect/Effect.js.map +1 -1
- package/dist/effect/Effect.test.d.ts +2 -0
- package/dist/effect/Effect.test.d.ts.map +1 -0
- package/dist/effect/Effect.test.js +72 -0
- package/dist/effect/Effect.test.js.map +1 -0
- package/dist/effect/Error.d.ts +4 -6
- package/dist/effect/Error.d.ts.map +1 -1
- package/dist/effect/Logger.d.ts +0 -6
- package/dist/effect/Logger.d.ts.map +1 -1
- package/dist/effect/Logger.js +0 -32
- package/dist/effect/Logger.js.map +1 -1
- package/dist/effect/OtelTracer.d.ts +1 -1
- package/dist/effect/OtelTracer.d.ts.map +1 -1
- package/dist/effect/OtelTracer.js +2 -3
- package/dist/effect/OtelTracer.js.map +1 -1
- package/dist/effect/RpcClient.d.ts +9 -9
- package/dist/effect/RpcClient.d.ts.map +1 -1
- package/dist/effect/RpcClient.js +113 -84
- package/dist/effect/RpcClient.js.map +1 -1
- package/dist/effect/Schedule.d.ts +1 -1
- package/dist/effect/Schedule.d.ts.map +1 -1
- package/dist/effect/Schedule.js +2 -2
- package/dist/effect/Schedule.js.map +1 -1
- package/dist/effect/Schema/debug-diff.d.ts +1 -1
- package/dist/effect/Schema/debug-diff.d.ts.map +1 -1
- package/dist/effect/Schema/debug-diff.js +5 -7
- package/dist/effect/Schema/debug-diff.js.map +1 -1
- package/dist/effect/Schema/debug-diff.test.js +8 -5
- package/dist/effect/Schema/debug-diff.test.js.map +1 -1
- package/dist/effect/Schema/index.d.ts +28 -20
- package/dist/effect/Schema/index.d.ts.map +1 -1
- package/dist/effect/Schema/index.js +56 -29
- package/dist/effect/Schema/index.js.map +1 -1
- package/dist/effect/Stream.d.ts +13 -5
- package/dist/effect/Stream.d.ts.map +1 -1
- package/dist/effect/Stream.js +19 -12
- package/dist/effect/Stream.js.map +1 -1
- package/dist/effect/Stream.test.js +10 -10
- package/dist/effect/Stream.test.js.map +1 -1
- package/dist/effect/Subscribable.d.ts +9 -3
- package/dist/effect/Subscribable.d.ts.map +1 -1
- package/dist/effect/Subscribable.js +20 -35
- package/dist/effect/Subscribable.js.map +1 -1
- package/dist/effect/SubscriptionRef.d.ts +5 -6
- package/dist/effect/SubscriptionRef.d.ts.map +1 -1
- package/dist/effect/SubscriptionRef.js +2 -3
- package/dist/effect/SubscriptionRef.js.map +1 -1
- package/dist/effect/TaskTracing.d.ts +1 -1
- package/dist/effect/TaskTracing.d.ts.map +1 -1
- package/dist/effect/TaskTracing.js +12 -16
- package/dist/effect/TaskTracing.js.map +1 -1
- package/dist/effect/WebChannel/WebChannel.d.ts +7 -7
- package/dist/effect/WebChannel/WebChannel.d.ts.map +1 -1
- package/dist/effect/WebChannel/WebChannel.js +69 -48
- package/dist/effect/WebChannel/WebChannel.js.map +1 -1
- package/dist/effect/WebChannel/WebChannel.test.js +16 -16
- package/dist/effect/WebChannel/WebChannel.test.js.map +1 -1
- package/dist/effect/WebChannel/broadcastChannelWithAck.d.ts.map +1 -1
- package/dist/effect/WebChannel/broadcastChannelWithAck.js +18 -11
- package/dist/effect/WebChannel/broadcastChannelWithAck.js.map +1 -1
- package/dist/effect/WebChannel/common.d.ts +16 -17
- package/dist/effect/WebChannel/common.d.ts.map +1 -1
- package/dist/effect/WebChannel/common.js +6 -6
- package/dist/effect/WebChannel/common.js.map +1 -1
- package/dist/effect/WebChannel/mod.js +3 -3
- package/dist/effect/WebSocket.d.ts +4 -6
- package/dist/effect/WebSocket.d.ts.map +1 -1
- package/dist/effect/WebSocket.js +4 -4
- package/dist/effect/WebSocket.js.map +1 -1
- package/dist/effect/WebSocket.test.js +3 -3
- package/dist/effect/WebSocket.test.js.map +1 -1
- package/dist/effect/mod.browser-build.test.d.ts +2 -0
- package/dist/effect/mod.browser-build.test.d.ts.map +1 -0
- package/dist/effect/mod.browser-build.test.js +18 -0
- package/dist/effect/mod.browser-build.test.js.map +1 -0
- package/dist/effect/mod.d.ts +13 -15
- package/dist/effect/mod.d.ts.map +1 -1
- package/dist/effect/mod.js +28 -33
- package/dist/effect/mod.js.map +1 -1
- package/dist/effect/spanEvent.d.ts.map +1 -1
- package/dist/effect/spanEvent.js +2 -2
- package/dist/effect/spanEvent.js.map +1 -1
- package/dist/effect/spanEvent.test.js +11 -14
- package/dist/effect/spanEvent.test.js.map +1 -1
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +1 -1
- package/dist/env.js.map +1 -1
- package/dist/fast-deep-equal.d.ts.map +1 -1
- package/dist/fast-deep-equal.js +1 -2
- package/dist/fast-deep-equal.js.map +1 -1
- package/dist/misc.d.ts.map +1 -1
- package/dist/misc.js +3 -3
- package/dist/misc.js.map +1 -1
- package/dist/mod.d.ts +1 -36
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +19 -27
- package/dist/mod.js.map +1 -1
- package/dist/node/mod.d.ts +11 -36
- package/dist/node/mod.d.ts.map +1 -1
- package/dist/node/mod.js +17 -42
- package/dist/node/mod.js.map +1 -1
- package/dist/object/index.d.ts +0 -9
- package/dist/object/index.d.ts.map +1 -1
- package/dist/object/index.js +1 -10
- package/dist/object/index.js.map +1 -1
- package/dist/object/stringify-object.d.ts.map +1 -1
- package/dist/object/stringify-object.test.js +1 -1
- package/dist/promise.d.ts.map +1 -1
- package/dist/qr.d.ts.map +1 -1
- package/dist/set.d.ts.map +1 -1
- package/dist/string.d.ts +0 -2
- package/dist/string.d.ts.map +1 -1
- package/dist/string.js +0 -2
- package/dist/string.js.map +1 -1
- package/package.json +38 -56
- package/src/NoopTracer.test.ts +36 -0
- package/src/NoopTracer.ts +18 -41
- package/src/browser/Opfs/Opfs.ts +304 -277
- package/src/browser/Opfs/debug-utils.ts +7 -6
- package/src/browser/Opfs/utils.ts +36 -26
- package/src/browser/QuotaExceededError.ts +13 -10
- package/src/browser/WebChannelBrowser.ts +25 -11
- package/src/browser/WebError.test.ts +6 -6
- package/src/browser/WebError.ts +107 -133
- package/src/browser/WebLock.ts +13 -14
- package/src/effect/Debug.ts +69 -78
- package/src/effect/Effect.test.ts +117 -0
- package/src/effect/Effect.ts +86 -73
- package/src/effect/Logger.ts +0 -48
- package/src/effect/OtelTracer.ts +2 -3
- package/src/effect/RpcClient.ts +126 -93
- package/src/effect/Schedule.ts +4 -5
- package/src/effect/Schema/debug-diff.test.ts +6 -6
- package/src/effect/Schema/debug-diff.ts +6 -8
- package/src/effect/Schema/index.ts +122 -61
- package/src/effect/Stream.test.ts +9 -9
- package/src/effect/Stream.ts +23 -16
- package/src/effect/Subscribable.ts +31 -42
- package/src/effect/SubscriptionRef.ts +8 -12
- package/src/effect/TaskTracing.ts +13 -16
- package/src/effect/WebChannel/WebChannel.test.ts +23 -23
- package/src/effect/WebChannel/WebChannel.ts +87 -56
- package/src/effect/WebChannel/broadcastChannelWithAck.ts +21 -11
- package/src/effect/WebChannel/common.ts +14 -15
- package/src/effect/WebSocket.test.ts +2 -2
- package/src/effect/WebSocket.ts +9 -6
- package/src/effect/mod.browser-build.test.ts +19 -0
- package/src/effect/mod.ts +37 -69
- package/src/effect/spanEvent.test.ts +10 -13
- package/src/effect/spanEvent.ts +5 -3
- package/src/fast-deep-equal.ts +4 -5
- package/src/misc.ts +3 -3
- package/src/mod.ts +5 -41
- package/src/node/mod.ts +20 -46
- package/src/object/index.ts +0 -24
- package/src/string.ts +0 -3
- package/dist/effect/BucketQueue.d.ts +0 -20
- package/dist/effect/BucketQueue.d.ts.map +0 -1
- package/dist/effect/BucketQueue.js +0 -34
- package/dist/effect/BucketQueue.js.map +0 -1
- package/dist/effect/Scheduler.d.ts +0 -4
- package/dist/effect/Scheduler.d.ts.map +0 -1
- package/dist/effect/Scheduler.js +0 -9
- package/dist/effect/Scheduler.js.map +0 -1
- package/dist/effect/ServiceContext.d.ts +0 -37
- package/dist/effect/ServiceContext.d.ts.map +0 -1
- package/dist/effect/ServiceContext.js +0 -55
- package/dist/effect/ServiceContext.js.map +0 -1
- package/dist/guards.d.ts +0 -20
- package/dist/guards.d.ts.map +0 -1
- package/dist/guards.js +0 -20
- package/dist/guards.js.map +0 -1
- package/dist/node/ChildProcessRunner/ChildProcessRunner.d.ts +0 -4
- package/dist/node/ChildProcessRunner/ChildProcessRunner.d.ts.map +0 -1
- package/dist/node/ChildProcessRunner/ChildProcessRunner.js +0 -128
- package/dist/node/ChildProcessRunner/ChildProcessRunner.js.map +0 -1
- package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/ChildProcessRunner.test.d.ts +0 -10
- package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/ChildProcessRunner.test.d.ts.map +0 -1
- package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/ChildProcessRunner.test.js +0 -217
- package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/ChildProcessRunner.test.js.map +0 -1
- package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/schema.d.ts +0 -84
- package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/schema.d.ts.map +0 -1
- package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/schema.js +0 -68
- package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/schema.js.map +0 -1
- package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/serializedWorker.d.ts +0 -2
- package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/serializedWorker.d.ts.map +0 -1
- package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/serializedWorker.js +0 -52
- package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/serializedWorker.js.map +0 -1
- package/dist/node/ChildProcessRunner/ChildProcessWorker.d.ts +0 -23
- package/dist/node/ChildProcessRunner/ChildProcessWorker.d.ts.map +0 -1
- package/dist/node/ChildProcessRunner/ChildProcessWorker.js +0 -138
- package/dist/node/ChildProcessRunner/ChildProcessWorker.js.map +0 -1
- package/dist/object/omit.d.ts +0 -3
- package/dist/object/omit.d.ts.map +0 -1
- package/dist/object/omit.js +0 -14
- package/dist/object/omit.js.map +0 -1
- package/dist/object/pick.d.ts +0 -14
- package/dist/object/pick.d.ts.map +0 -1
- package/dist/object/pick.js +0 -17
- package/dist/object/pick.js.map +0 -1
- package/dist/time.d.ts +0 -12
- package/dist/time.d.ts.map +0 -1
- package/dist/time.js +0 -22
- package/dist/time.js.map +0 -1
- package/src/effect/BucketQueue.ts +0 -49
- package/src/effect/Scheduler.ts +0 -13
- package/src/effect/ServiceContext.ts +0 -108
- package/src/guards.ts +0 -23
- package/src/node/ChildProcessRunner/ChildProcessRunner.ts +0 -148
- package/src/node/ChildProcessRunner/ChildProcessRunnerTest/ChildProcessRunner.test.ts +0 -311
- package/src/node/ChildProcessRunner/ChildProcessRunnerTest/schema.ts +0 -78
- package/src/node/ChildProcessRunner/ChildProcessRunnerTest/serializedWorker.ts +0 -65
- package/src/node/ChildProcessRunner/ChildProcessWorker.ts +0 -169
- package/src/object/omit.ts +0 -17
- package/src/object/pick.ts +0 -27
- package/src/time.ts +0 -25
package/src/effect/RpcClient.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
export * from '
|
|
1
|
+
export * from 'effect/rpc/RpcClient'
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { RpcClient, RpcClientError, RpcSerialization } from '
|
|
5
|
-
import { Protocol } from '
|
|
6
|
-
import { constPing, type FromServerEncoded } from '
|
|
7
|
-
import {
|
|
8
|
-
import { constVoid, identity } from 'effect/Function'
|
|
3
|
+
import { Cause, Deferred, Effect, Function, Latch, Layer, References, Result, Schedule, type Scope } from 'effect'
|
|
4
|
+
import { RpcClient, RpcClientError, RpcSerialization } from 'effect/rpc'
|
|
5
|
+
import { Protocol } from 'effect/rpc/RpcClient'
|
|
6
|
+
import { constPing, type FromServerEncoded } from 'effect/rpc/RpcMessage'
|
|
7
|
+
import { Socket } from 'effect/socket'
|
|
9
8
|
|
|
10
9
|
import * as SubscriptionRef from './SubscriptionRef.ts'
|
|
11
10
|
|
|
@@ -20,7 +19,7 @@ export const layerProtocolSocketWithIsConnected = (options: {
|
|
|
20
19
|
readonly isConnected: SubscriptionRef.SubscriptionRef<boolean>
|
|
21
20
|
readonly pingSchedule?: Schedule.Schedule<unknown> | undefined
|
|
22
21
|
}): Layer.Layer<Protocol, never, RpcSerialization.RpcSerialization | Socket.Socket> =>
|
|
23
|
-
Layer.
|
|
22
|
+
Layer.effect(Protocol, makeProtocolSocketWithIsConnected(options))
|
|
24
23
|
|
|
25
24
|
export const makeProtocolSocketWithIsConnected = (options: {
|
|
26
25
|
readonly url: string
|
|
@@ -29,135 +28,169 @@ export const makeProtocolSocketWithIsConnected = (options: {
|
|
|
29
28
|
readonly isConnected: SubscriptionRef.SubscriptionRef<boolean>
|
|
30
29
|
// CHANGED: add ping schedule
|
|
31
30
|
readonly pingSchedule?: Schedule.Schedule<unknown> | undefined
|
|
32
|
-
}): Effect.Effect<Protocol['
|
|
31
|
+
}): Effect.Effect<Protocol['Service'], never, Scope.Scope | RpcSerialization.RpcSerialization | Socket.Socket> =>
|
|
33
32
|
Protocol.make(
|
|
34
|
-
Effect.fnUntraced(function* (writeResponse) {
|
|
33
|
+
Effect.fnUntraced(function* (writeResponse, clientIds) {
|
|
35
34
|
const socket = yield* Socket.Socket
|
|
36
35
|
const serialization = yield* RpcSerialization.RpcSerialization
|
|
36
|
+
const requestClientMap = new Map<string | number, number>()
|
|
37
37
|
|
|
38
|
-
const
|
|
39
|
-
|
|
38
|
+
const writer = yield* socket.writer
|
|
39
|
+
let parser = serialization.makeUnsafe()
|
|
40
40
|
|
|
41
|
-
const pinger = yield* makePinger(
|
|
41
|
+
const pinger = yield* makePinger(
|
|
42
|
+
Effect.suspend(() => {
|
|
43
|
+
const encoded = parser.encode(constPing)
|
|
44
|
+
return encoded === undefined ? Effect.void : writer.write(encoded)
|
|
45
|
+
}),
|
|
46
|
+
options?.pingSchedule,
|
|
47
|
+
)
|
|
48
|
+
let currentError: RpcClientError.RpcClientError | undefined
|
|
49
|
+
|
|
50
|
+
const markConnected = SubscriptionRef.set(options.isConnected, true)
|
|
51
|
+
const broadcast = (response: FromServerEncoded) =>
|
|
52
|
+
Effect.forEach(clientIds, (clientId) => writeResponse(clientId, response))
|
|
53
|
+
|
|
54
|
+
const processData = (message: Uint8Array | string): Effect.Effect<void> => {
|
|
55
|
+
try {
|
|
56
|
+
const responses = parser.decode(message) as Array<FromServerEncoded>
|
|
57
|
+
if (responses.length === 0) return Effect.void
|
|
58
|
+
let i = 0
|
|
59
|
+
return Effect.whileLoop({
|
|
60
|
+
while: () => i < responses.length,
|
|
61
|
+
body: () => {
|
|
62
|
+
const response = responses[i++]!
|
|
63
|
+
pinger.reset()
|
|
64
|
+
if (response._tag === 'Pong') {
|
|
65
|
+
pinger.onPong()
|
|
66
|
+
return markConnected
|
|
67
|
+
}
|
|
68
|
+
if ('requestId' in response) {
|
|
69
|
+
const clientId = requestClientMap.get(response.requestId)
|
|
70
|
+
if (clientId !== undefined) {
|
|
71
|
+
if (response._tag === 'Exit') {
|
|
72
|
+
requestClientMap.delete(response.requestId)
|
|
73
|
+
}
|
|
74
|
+
return markConnected.pipe(Effect.andThen(writeResponse(clientId, response)))
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return markConnected.pipe(Effect.andThen(broadcast(response)))
|
|
78
|
+
},
|
|
79
|
+
step: Function.constVoid,
|
|
80
|
+
})
|
|
81
|
+
} catch (defect) {
|
|
82
|
+
return broadcast({
|
|
83
|
+
_tag: 'ClientProtocolError',
|
|
84
|
+
error: new RpcClientError.RpcClientError({
|
|
85
|
+
reason: new RpcClientError.RpcClientDefect({
|
|
86
|
+
message: 'Error decoding message',
|
|
87
|
+
cause: defect,
|
|
88
|
+
}),
|
|
89
|
+
}),
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
}
|
|
42
93
|
|
|
43
94
|
yield* Effect.suspend(() => {
|
|
44
95
|
// We rely on the heartbeat watchdog while streaming arbitrarily long payloads.
|
|
45
96
|
// Reset the timer as soon as _any_ frame arrives so that large batches which
|
|
46
97
|
// don't contain explicit `Pong` messages don't trigger the open-timeout defect.
|
|
47
98
|
// (The actual pong handler still calls `onPong()` to resolve manual pings.)
|
|
48
|
-
|
|
49
|
-
// parser = serialization.unsafeMake()
|
|
99
|
+
parser = serialization.makeUnsafe()
|
|
50
100
|
pinger.reset()
|
|
51
|
-
return
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
body: () => {
|
|
60
|
-
const response = responses[i++]!
|
|
61
|
-
// Keep extending the watchdog for each data frame to avoid
|
|
62
|
-
// disconnecting mid-stream when the server is busy sending batches.
|
|
63
|
-
pinger.reset()
|
|
64
|
-
if (response._tag === 'Pong') {
|
|
65
|
-
pinger.onPong()
|
|
66
|
-
}
|
|
67
|
-
return writeResponse(response).pipe(
|
|
68
|
-
// CHANGED: set isConnected to true on pong
|
|
69
|
-
Effect.tap(
|
|
70
|
-
Effect.fn(function* () {
|
|
71
|
-
if (options?.isConnected !== undefined) {
|
|
72
|
-
yield* SubscriptionRef.set(options.isConnected, true)
|
|
73
|
-
}
|
|
74
|
-
}),
|
|
75
|
-
),
|
|
76
|
-
)
|
|
77
|
-
},
|
|
78
|
-
step: constVoid,
|
|
79
|
-
})
|
|
80
|
-
} catch (defect) {
|
|
81
|
-
return writeResponse({
|
|
82
|
-
_tag: 'ClientProtocolError',
|
|
83
|
-
error: new RpcClientError.RpcClientError({
|
|
84
|
-
reason: 'Protocol',
|
|
85
|
-
message: 'Error decoding message',
|
|
86
|
-
cause: Cause.fail(defect),
|
|
87
|
-
}),
|
|
88
|
-
})
|
|
101
|
+
return Effect.gen(function* () {
|
|
102
|
+
const { pull } = yield* socket.reader
|
|
103
|
+
currentError = undefined
|
|
104
|
+
while (true) {
|
|
105
|
+
const frames = yield* pull
|
|
106
|
+
for (const frame of frames) {
|
|
107
|
+
// Keep extending the watchdog for each data frame to avoid disconnecting mid-stream.
|
|
108
|
+
yield* processData(frame)
|
|
89
109
|
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
110
|
+
}
|
|
111
|
+
}).pipe(
|
|
112
|
+
Effect.scoped,
|
|
113
|
+
Effect.raceFirst(
|
|
114
|
+
Effect.flatMap(pinger.timeout, () =>
|
|
115
|
+
Effect.fail(
|
|
116
|
+
new Socket.SocketError({
|
|
117
|
+
reason: new Socket.SocketOpenError({
|
|
118
|
+
kind: 'Timeout',
|
|
98
119
|
cause: new Error('ping timeout'),
|
|
99
120
|
}),
|
|
100
|
-
),
|
|
121
|
+
}),
|
|
101
122
|
),
|
|
102
123
|
),
|
|
103
|
-
)
|
|
124
|
+
),
|
|
125
|
+
)
|
|
104
126
|
}).pipe(
|
|
105
|
-
Effect.
|
|
127
|
+
Effect.flatMap(() =>
|
|
106
128
|
Effect.fail(
|
|
107
|
-
new Socket.
|
|
108
|
-
reason:
|
|
109
|
-
|
|
110
|
-
|
|
129
|
+
new Socket.SocketError({
|
|
130
|
+
reason: new Socket.SocketCloseError({
|
|
131
|
+
code: 1000,
|
|
132
|
+
closeReason: 'Closing connection',
|
|
133
|
+
}),
|
|
111
134
|
}),
|
|
112
135
|
),
|
|
113
136
|
),
|
|
114
|
-
Effect.
|
|
137
|
+
Effect.tapCause(
|
|
115
138
|
Effect.fn(function* (cause) {
|
|
116
139
|
// CHANGED: set isConnected to false on error
|
|
117
|
-
|
|
118
|
-
yield* SubscriptionRef.set(options.isConnected, false)
|
|
119
|
-
}
|
|
140
|
+
yield* SubscriptionRef.set(options.isConnected, false)
|
|
120
141
|
|
|
121
|
-
const error = Cause.
|
|
142
|
+
const error = Cause.findError(cause)
|
|
122
143
|
if (
|
|
123
144
|
options?.retryTransientErrors !== undefined &&
|
|
124
|
-
|
|
125
|
-
|
|
145
|
+
Result.isSuccess(error) === true &&
|
|
146
|
+
error.success.reason._tag === 'SocketOpenError'
|
|
126
147
|
) {
|
|
127
148
|
return
|
|
128
149
|
}
|
|
129
150
|
// yield* Effect.logError('Error in socket', cause)
|
|
130
|
-
|
|
151
|
+
currentError = new RpcClientError.RpcClientError({
|
|
152
|
+
reason:
|
|
153
|
+
Result.isSuccess(error) === true
|
|
154
|
+
? error.success.reason
|
|
155
|
+
: new RpcClientError.RpcClientDefect({
|
|
156
|
+
message: 'Unknown socket error',
|
|
157
|
+
cause: Cause.squash(cause),
|
|
158
|
+
}),
|
|
159
|
+
})
|
|
160
|
+
return yield* broadcast({
|
|
131
161
|
_tag: 'ClientProtocolError',
|
|
132
|
-
error:
|
|
133
|
-
reason: 'Protocol',
|
|
134
|
-
message: 'Error in socket',
|
|
135
|
-
cause: Cause.squash(cause),
|
|
136
|
-
}),
|
|
162
|
+
error: currentError,
|
|
137
163
|
})
|
|
138
164
|
}),
|
|
139
165
|
),
|
|
140
166
|
// CHANGED: make configurable via schedule
|
|
141
|
-
options?.retryTransientErrors !== undefined ? Effect.retry(options.retryTransientErrors) : identity,
|
|
167
|
+
options?.retryTransientErrors !== undefined ? Effect.retry(options.retryTransientErrors) : Function.identity,
|
|
142
168
|
Effect.annotateLogs({
|
|
143
169
|
module: 'RpcClient',
|
|
144
170
|
method: 'makeProtocolSocket',
|
|
145
171
|
}),
|
|
146
172
|
Effect.interruptible,
|
|
147
173
|
Effect.ignore, // Errors are already handled
|
|
148
|
-
Effect.
|
|
174
|
+
Effect.provideService(References.UnhandledLogLevel, undefined),
|
|
149
175
|
Effect.forkScoped,
|
|
150
176
|
)
|
|
151
177
|
|
|
152
178
|
return {
|
|
153
|
-
send: (request) => {
|
|
179
|
+
send: (clientId, request) => {
|
|
180
|
+
if (currentError !== undefined) {
|
|
181
|
+
return Effect.fail(currentError)
|
|
182
|
+
}
|
|
183
|
+
if (request._tag === 'Request') {
|
|
184
|
+
requestClientMap.set(request.id, clientId)
|
|
185
|
+
}
|
|
154
186
|
const encoded = parser.encode(request)
|
|
155
187
|
if (encoded === undefined) return Effect.void
|
|
156
188
|
|
|
157
|
-
return Effect.orDie(write(encoded))
|
|
189
|
+
return Effect.orDie(writer.write(encoded))
|
|
158
190
|
},
|
|
159
191
|
supportsAck: true,
|
|
160
192
|
supportsTransferables: false,
|
|
193
|
+
codecFor: serialization.codecFor,
|
|
161
194
|
pinger,
|
|
162
195
|
}
|
|
163
196
|
}),
|
|
@@ -165,33 +198,33 @@ export const makeProtocolSocketWithIsConnected = (options: {
|
|
|
165
198
|
|
|
166
199
|
export const SocketPinger = Effect.map(RpcClient.Protocol, (protocol) => (protocol as any).pinger as SocketPinger)
|
|
167
200
|
|
|
168
|
-
export type SocketPinger = Effect.
|
|
201
|
+
export type SocketPinger = Effect.Success<ReturnType<typeof makePinger>>
|
|
169
202
|
|
|
170
203
|
const makePinger = Effect.fnUntraced(function* <A, E, R>(
|
|
171
204
|
writePing: Effect.Effect<A, E, R>,
|
|
172
|
-
pingSchedule: Schedule.Schedule<unknown> = Schedule.spaced(10000).pipe(Schedule.addDelay(() => 5000)),
|
|
205
|
+
pingSchedule: Schedule.Schedule<unknown> = Schedule.spaced(10000).pipe(Schedule.addDelay(() => Effect.succeed(5000))),
|
|
173
206
|
) {
|
|
174
207
|
// CHANGED: add manual ping deferreds
|
|
175
208
|
const manualPingDeferreds = new Set<Deferred.Deferred<void>>()
|
|
176
209
|
|
|
177
210
|
let recievedPong = true
|
|
178
|
-
const latch =
|
|
211
|
+
const latch = Latch.makeUnsafe()
|
|
179
212
|
const reset = () => {
|
|
180
213
|
recievedPong = true
|
|
181
|
-
latch.
|
|
214
|
+
latch.closeUnsafe()
|
|
182
215
|
}
|
|
183
216
|
const onPong = () => {
|
|
184
217
|
recievedPong = true
|
|
185
218
|
// CHANGED: mark all manual ping deferreds as done
|
|
186
219
|
for (const deferred of manualPingDeferreds) {
|
|
187
|
-
Deferred.
|
|
220
|
+
Deferred.doneUnsafe(deferred, Effect.void)
|
|
188
221
|
}
|
|
189
222
|
}
|
|
190
223
|
yield* Effect.suspend(() => {
|
|
191
224
|
// Starting new ping
|
|
192
|
-
if (recievedPong === false) return latch.open
|
|
225
|
+
if (recievedPong === false) return Effect.asVoid(latch.open)
|
|
193
226
|
recievedPong = false
|
|
194
|
-
return writePing
|
|
227
|
+
return Effect.asVoid(writePing)
|
|
195
228
|
}).pipe(
|
|
196
229
|
// CHANGED: make configurable via schedule
|
|
197
230
|
Effect.schedule(pingSchedule),
|
|
@@ -205,7 +238,7 @@ const makePinger = Effect.fnUntraced(function* <A, E, R>(
|
|
|
205
238
|
const ping = Effect.gen(function* () {
|
|
206
239
|
const deferred = yield* Deferred.make<void>()
|
|
207
240
|
manualPingDeferreds.add(deferred)
|
|
208
|
-
yield* deferred
|
|
241
|
+
yield* Deferred.await(deferred)
|
|
209
242
|
manualPingDeferreds.delete(deferred)
|
|
210
243
|
})
|
|
211
244
|
|
package/src/effect/Schedule.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { Duration, pipe, Schedule } from 'effect'
|
|
1
|
+
import { Duration, Effect, pipe, Schedule } from 'effect'
|
|
2
2
|
|
|
3
3
|
export * from 'effect/Schedule'
|
|
4
4
|
|
|
5
|
-
export const exponentialBackoff10Sec
|
|
5
|
+
export const exponentialBackoff10Sec = pipe(
|
|
6
6
|
Schedule.exponential(Duration.millis(10), 4), // 10ms, 40ms, 160ms, 640ms, 2560ms, ...
|
|
7
|
-
Schedule.
|
|
8
|
-
Schedule.
|
|
9
|
-
Schedule.whileOutput(Duration.lessThanOrEqualTo(Duration.seconds(10))), // max 10 seconds
|
|
7
|
+
Schedule.modifyDelay(({ duration }) => Effect.succeed(Duration.min(duration, Duration.seconds(1)))),
|
|
8
|
+
Schedule.upTo({ duration: Duration.seconds(10) }),
|
|
10
9
|
)
|
|
@@ -8,7 +8,7 @@ describe('debug-diff', () => {
|
|
|
8
8
|
test('simple object', () => {
|
|
9
9
|
const schema = Schema.Struct({
|
|
10
10
|
a: Schema.String,
|
|
11
|
-
b: Schema.
|
|
11
|
+
b: Schema.Finite,
|
|
12
12
|
})
|
|
13
13
|
|
|
14
14
|
const a = { a: 'hello', b: 1 }
|
|
@@ -35,7 +35,7 @@ describe('debug-diff', () => {
|
|
|
35
35
|
const schema = Schema.Struct({
|
|
36
36
|
a: Schema.String,
|
|
37
37
|
b: Schema.Struct({
|
|
38
|
-
c: Schema.
|
|
38
|
+
c: Schema.Finite,
|
|
39
39
|
}),
|
|
40
40
|
})
|
|
41
41
|
const a = { a: 'hello', b: { c: 1 } }
|
|
@@ -58,7 +58,7 @@ describe('debug-diff', () => {
|
|
|
58
58
|
})
|
|
59
59
|
|
|
60
60
|
test('union', () => {
|
|
61
|
-
const schema = Schema.Union(Schema.String, Schema.
|
|
61
|
+
const schema = Schema.Union([Schema.String, Schema.Finite])
|
|
62
62
|
const a = 'hello'
|
|
63
63
|
const b = 1
|
|
64
64
|
const diff = debugDiff(schema)(a, b)
|
|
@@ -74,10 +74,10 @@ describe('debug-diff', () => {
|
|
|
74
74
|
})
|
|
75
75
|
|
|
76
76
|
test('tagged union', () => {
|
|
77
|
-
const schema = Schema.Union(
|
|
77
|
+
const schema = Schema.Union([
|
|
78
78
|
Schema.TaggedStruct('a', { a: Schema.String }),
|
|
79
|
-
Schema.TaggedStruct('b', { b: Schema.
|
|
80
|
-
)
|
|
79
|
+
Schema.TaggedStruct('b', { b: Schema.Finite }),
|
|
80
|
+
])
|
|
81
81
|
const a = { _tag: 'a', a: 'hello' } as const
|
|
82
82
|
const b = { _tag: 'b', b: 1 } as const
|
|
83
83
|
const diff = debugDiff(schema)(a, b)
|
|
@@ -11,7 +11,7 @@ export type DiffItem = {
|
|
|
11
11
|
* Diffs two values for a given schema and traverses downwards and returns a list of differences.
|
|
12
12
|
*/
|
|
13
13
|
export const debugDiff =
|
|
14
|
-
<A, I, R>(base: Schema.
|
|
14
|
+
<A, I, R>(base: Schema.Top) =>
|
|
15
15
|
(a: A, b: A): DiffItem[] => {
|
|
16
16
|
const bag = [] as DiffItem[]
|
|
17
17
|
debugDiffImpl(base.ast, a, b, '', bag)
|
|
@@ -19,7 +19,7 @@ export const debugDiff =
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
const debugDiffImpl = (ast: SchemaAST.AST, a: any, b: any, path: string, bag: DiffItem[]) => {
|
|
22
|
-
const eq = Schema.
|
|
22
|
+
const eq = Schema.toEquivalence({ ast } as any)
|
|
23
23
|
if (eq(a, b) === false) {
|
|
24
24
|
// bag.push({ path, a, b, ast })
|
|
25
25
|
|
|
@@ -35,9 +35,8 @@ const debugDiffImpl = (ast: SchemaAST.AST, a: any, b: any, path: string, bag: Di
|
|
|
35
35
|
} catch {}
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
} else if (SchemaAST.
|
|
39
|
-
const
|
|
40
|
-
for (const prop of props) {
|
|
38
|
+
} else if (SchemaAST.isObjects(ast) === true) {
|
|
39
|
+
for (const prop of ast.propertySignatures) {
|
|
41
40
|
debugDiffImpl(prop.type, a[prop.name], b[prop.name], `${path}.${prop.name.toString()}`, bag)
|
|
42
41
|
}
|
|
43
42
|
} else {
|
|
@@ -50,9 +49,8 @@ const debugDiffImpl = (ast: SchemaAST.AST, a: any, b: any, path: string, bag: Di
|
|
|
50
49
|
const isTaggedUnion = (ast: SchemaAST.AST): boolean => {
|
|
51
50
|
if (SchemaAST.isUnion(ast) === true) {
|
|
52
51
|
return ast.types.every((type) => {
|
|
53
|
-
if (SchemaAST.
|
|
54
|
-
|
|
55
|
-
return props.some((prop) => prop.name.toString() === '_tag')
|
|
52
|
+
if (SchemaAST.isObjects(type) === false) return false
|
|
53
|
+
return type.propertySignatures.some((prop) => prop.name.toString() === '_tag')
|
|
56
54
|
})
|
|
57
55
|
}
|
|
58
56
|
return false
|
|
@@ -1,18 +1,115 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import {
|
|
2
|
+
Array,
|
|
3
|
+
Effect,
|
|
4
|
+
Function,
|
|
5
|
+
Hash,
|
|
6
|
+
Option,
|
|
7
|
+
Result,
|
|
8
|
+
Schema,
|
|
9
|
+
SchemaAST,
|
|
10
|
+
SchemaGetter,
|
|
11
|
+
SchemaIssue,
|
|
12
|
+
SchemaTransformation,
|
|
13
|
+
Struct,
|
|
14
|
+
} from 'effect'
|
|
15
|
+
import { Transferable } from 'effect/workers'
|
|
16
|
+
|
|
17
|
+
import { shouldNeverHappen } from '../../misc.ts'
|
|
8
18
|
|
|
9
19
|
export * from 'effect/Schema'
|
|
10
20
|
export * from './debug-diff.ts'
|
|
11
21
|
|
|
22
|
+
type PluckSchema<Fields extends Schema.Struct.Fields, K extends keyof Fields> = Schema.Codec<
|
|
23
|
+
Fields[K]['Type'],
|
|
24
|
+
Schema.Struct<Pick<Fields, K>>['Encoded'],
|
|
25
|
+
Schema.Struct<Pick<Fields, K>>['DecodingServices'],
|
|
26
|
+
Schema.Struct<Pick<Fields, K>>['EncodingServices']
|
|
27
|
+
>
|
|
28
|
+
|
|
29
|
+
export const pluck =
|
|
30
|
+
<const K extends PropertyKey>(key: K) =>
|
|
31
|
+
<Fields extends { readonly [P in K]: Schema.Top }>(
|
|
32
|
+
schema: Schema.Struct<Fields>,
|
|
33
|
+
): PluckSchema<Fields, K & keyof Fields> => {
|
|
34
|
+
const field = schema.fields[key] as Fields[K & keyof Fields]
|
|
35
|
+
|
|
36
|
+
return schema.mapFields(Struct.pick([key])).pipe(
|
|
37
|
+
Schema.decodeTo(Schema.toType(field), {
|
|
38
|
+
decode: SchemaGetter.transform((whole: any) => whole[key]),
|
|
39
|
+
encode: SchemaGetter.transform((value) => ({ [key]: value }) as any),
|
|
40
|
+
}),
|
|
41
|
+
) as unknown as PluckSchema<Fields, K & keyof Fields>
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Like {@link fromJsonString}, but the ENCODED form is an *indented* JSON string
|
|
46
|
+
* (default 2-space) instead of compact — for committed/human-read JSON files
|
|
47
|
+
* (package.json, release plans, CI previews) that must stay diff-friendly while
|
|
48
|
+
* still round-tripping through the schema.
|
|
49
|
+
*
|
|
50
|
+
* Use a concrete schema for known shapes (adds validation) or `Schema.Unknown`
|
|
51
|
+
* for open-ended ones (the indented analogue of `fromJsonString(Schema.Unknown)`).
|
|
52
|
+
*
|
|
53
|
+
* TODO collapse into `fromJsonString(schema, { space })` now that Effect 4 accepts a
|
|
54
|
+
* `space` option; kept separate here to keep the Effect upgrade free of release-tooling changes.
|
|
55
|
+
*/
|
|
56
|
+
export const jsonStringIndented = <S extends Schema.Top>(schema: S, space: number | string = 2) =>
|
|
57
|
+
schema.pipe(
|
|
58
|
+
Schema.encodeTo(Schema.String, {
|
|
59
|
+
decode: SchemaGetter.parseJson(),
|
|
60
|
+
encode: SchemaGetter.stringifyJson({ space }),
|
|
61
|
+
}),
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
export const head = <S extends Schema.Top>(
|
|
65
|
+
array: Schema.$Array<S>,
|
|
66
|
+
): Schema.decodeTo<Schema.Option<Schema.toType<S>>, Schema.$Array<S>> =>
|
|
67
|
+
array.pipe(
|
|
68
|
+
Schema.decodeTo(
|
|
69
|
+
Schema.Option(Schema.toType(array.value)),
|
|
70
|
+
SchemaTransformation.transform({
|
|
71
|
+
decode: Array.head,
|
|
72
|
+
encode: Option.match({
|
|
73
|
+
onNone: () => [],
|
|
74
|
+
onSome: Array.of,
|
|
75
|
+
}),
|
|
76
|
+
}),
|
|
77
|
+
),
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
type HeadOrElse<S extends Schema.Top> = Schema.decodeTo<Schema.toType<S>, Schema.$Array<S>>
|
|
81
|
+
|
|
82
|
+
export const headOrElse: {
|
|
83
|
+
<S extends Schema.Top>(array: Schema.$Array<S>, orElse?: () => S['Type']): HeadOrElse<S>
|
|
84
|
+
(): <S extends Schema.Top>(array: Schema.$Array<S>) => HeadOrElse<S>
|
|
85
|
+
<S extends Schema.Top>(orElse: () => S['Type']): (array: Schema.$Array<S>) => HeadOrElse<S>
|
|
86
|
+
} = Function.dual(
|
|
87
|
+
(args) => Schema.isSchema(args[0]),
|
|
88
|
+
<S extends Schema.Top>(array: Schema.$Array<S>, orElse?: () => S['Type']): HeadOrElse<S> =>
|
|
89
|
+
array.pipe(
|
|
90
|
+
Schema.decodeTo(
|
|
91
|
+
Schema.toType(array.value),
|
|
92
|
+
SchemaTransformation.transformEffect({
|
|
93
|
+
decode: (array) =>
|
|
94
|
+
Array.isReadonlyArrayNonEmpty(array) === true
|
|
95
|
+
? Effect.succeed(Array.headNonEmpty(array))
|
|
96
|
+
: orElse === undefined
|
|
97
|
+
? Effect.fail(
|
|
98
|
+
new SchemaIssue.InvalidValue({
|
|
99
|
+
message: 'Unable to retrieve the first element of an empty array',
|
|
100
|
+
}),
|
|
101
|
+
)
|
|
102
|
+
: Effect.succeed(orElse()),
|
|
103
|
+
encode: (value) => Effect.succeed(Array.of(value)),
|
|
104
|
+
}),
|
|
105
|
+
),
|
|
106
|
+
),
|
|
107
|
+
)
|
|
108
|
+
|
|
12
109
|
// NOTE this is a temporary workaround until Effect schema has a better way to hash schemas
|
|
13
110
|
// https://github.com/Effect-TS/effect/issues/2719
|
|
14
111
|
// TODO remove this once the issue is resolved
|
|
15
|
-
export const hash = (schema: Schema.
|
|
112
|
+
export const hash = (schema: Schema.Top) => {
|
|
16
113
|
try {
|
|
17
114
|
return Hash.string(JSON.stringify(schema.ast, null, 2))
|
|
18
115
|
} catch {
|
|
@@ -23,80 +120,44 @@ export const hash = (schema: Schema.Schema<any>) => {
|
|
|
23
120
|
}
|
|
24
121
|
}
|
|
25
122
|
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return ast
|
|
123
|
+
export const getResolvedPropertySignatures = (schema: Schema.Top): ReadonlyArray<SchemaAST.PropertySignature> => {
|
|
124
|
+
const resolvedAst = SchemaAST.toType(schema.ast)
|
|
125
|
+
return SchemaAST.isObjects(resolvedAst) === true ? resolvedAst.propertySignatures : []
|
|
32
126
|
}
|
|
33
127
|
|
|
34
|
-
export const getResolvedPropertySignatures = (
|
|
35
|
-
schema: Schema.Schema.AnyNoContext,
|
|
36
|
-
): ReadonlyArray<SchemaAST.PropertySignature> => {
|
|
37
|
-
const resolvedAst = resolveStructAst(schema.ast)
|
|
38
|
-
return SchemaAST.getPropertySignatures(resolvedAst)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/** Objects that can be transferred between contexts (workers, etc.) */
|
|
42
|
-
type TransferableObject = ArrayBuffer | MessagePort
|
|
43
|
-
|
|
44
128
|
export const encodeWithTransferables =
|
|
45
|
-
<A, I
|
|
46
|
-
(a: A, overrideOptions?: ParseOptions)
|
|
129
|
+
<A, I>(schema: Schema.Codec<A, I>, options?: SchemaAST.ParseOptions) =>
|
|
130
|
+
(a: A, overrideOptions?: SchemaAST.ParseOptions) =>
|
|
47
131
|
Effect.gen(function* () {
|
|
48
132
|
const collector = yield* Transferable.makeCollector
|
|
49
133
|
|
|
50
|
-
const encoded
|
|
134
|
+
const encoded = yield* Schema.encodeEffect(schema, options)(a, overrideOptions).pipe(
|
|
51
135
|
Effect.provideService(Transferable.Collector, collector),
|
|
52
136
|
)
|
|
53
137
|
|
|
54
|
-
return [encoded, collector.
|
|
138
|
+
return [encoded, collector.readUnsafe()] as const
|
|
55
139
|
})
|
|
56
140
|
|
|
57
141
|
export const decodeSyncDebug: <A, I>(
|
|
58
|
-
schema: Schema.
|
|
142
|
+
schema: Schema.Codec<A, I>,
|
|
59
143
|
options?: SchemaAST.ParseOptions,
|
|
60
144
|
) => (i: I, overrideOptions?: SchemaAST.ParseOptions) => A = (schema, options) => (input, overrideOptions) => {
|
|
61
|
-
const res = Schema.
|
|
62
|
-
if (res
|
|
63
|
-
return shouldNeverHappen(`decodeSyncDebug failed:`, res.
|
|
145
|
+
const res = Schema.decodeResult(schema, options)(input, overrideOptions)
|
|
146
|
+
if (Result.isFailure(res) === true) {
|
|
147
|
+
return shouldNeverHappen(`decodeSyncDebug failed:`, res.failure)
|
|
64
148
|
} else {
|
|
65
|
-
return res.
|
|
149
|
+
return res.success
|
|
66
150
|
}
|
|
67
151
|
}
|
|
68
152
|
|
|
69
153
|
export const encodeSyncDebug: <A, I>(
|
|
70
|
-
schema: Schema.
|
|
154
|
+
schema: Schema.Codec<A, I>,
|
|
71
155
|
options?: SchemaAST.ParseOptions,
|
|
72
156
|
) => (a: A, overrideOptions?: SchemaAST.ParseOptions) => I = (schema, options) => (input, overrideOptions) => {
|
|
73
|
-
const res = Schema.
|
|
74
|
-
if (res
|
|
75
|
-
return shouldNeverHappen(`encodeSyncDebug failed:`, res.
|
|
157
|
+
const res = Schema.encodeResult(schema, options)(input, overrideOptions)
|
|
158
|
+
if (Result.isFailure(res) === true) {
|
|
159
|
+
return shouldNeverHappen(`encodeSyncDebug failed:`, res.failure)
|
|
76
160
|
} else {
|
|
77
|
-
return res.
|
|
161
|
+
return res.success
|
|
78
162
|
}
|
|
79
163
|
}
|
|
80
|
-
|
|
81
|
-
export const swap = <A, I, R>(schema: Schema.Schema<A, I, R>): Schema.Schema<I, A, R> =>
|
|
82
|
-
Schema.transformOrFail(Schema.typeSchema(schema), Schema.encodedSchema(schema), {
|
|
83
|
-
decode: ParseResult.encode(schema),
|
|
84
|
-
encode: ParseResult.decode(schema),
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
export const Base64FromUint8Array: Schema.Schema<string, Uint8Array> = swap(Schema.Uint8ArrayFromBase64)
|
|
88
|
-
|
|
89
|
-
export interface JsonArray extends ReadonlyArray<JsonValue> {}
|
|
90
|
-
export interface JsonObject {
|
|
91
|
-
[key: string]: JsonValue
|
|
92
|
-
}
|
|
93
|
-
export type JsonValue = string | number | boolean | null | JsonObject | JsonArray
|
|
94
|
-
|
|
95
|
-
export const JsonValue: Schema.Schema<JsonValue> = Schema.Union(
|
|
96
|
-
Schema.String,
|
|
97
|
-
Schema.Number,
|
|
98
|
-
Schema.Boolean,
|
|
99
|
-
Schema.Null,
|
|
100
|
-
Schema.Array(Schema.suspend(() => JsonValue)),
|
|
101
|
-
Schema.Record({ key: Schema.String, value: Schema.suspend(() => JsonValue) }),
|
|
102
|
-
).annotations({ identifier: 'JsonValue' })
|