@livestore/sync-cf 0.4.0-dev.22 → 0.4.0-dev.23
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 +6 -7
- package/dist/.tsbuildinfo +1 -1
- package/dist/cf-worker/do/durable-object.d.ts.map +1 -1
- package/dist/cf-worker/do/durable-object.js +5 -5
- package/dist/cf-worker/do/durable-object.js.map +1 -1
- package/dist/cf-worker/do/layer.d.ts +1 -1
- package/dist/cf-worker/do/layer.d.ts.map +1 -1
- package/dist/cf-worker/do/layer.js +2 -2
- package/dist/cf-worker/do/layer.js.map +1 -1
- package/dist/cf-worker/do/pull.d.ts +2 -2
- package/dist/cf-worker/do/pull.d.ts.map +1 -1
- package/dist/cf-worker/do/pull.js +11 -5
- package/dist/cf-worker/do/pull.js.map +1 -1
- package/dist/cf-worker/do/push.d.ts +2 -2
- package/dist/cf-worker/do/push.d.ts.map +1 -1
- package/dist/cf-worker/do/push.js +16 -9
- package/dist/cf-worker/do/push.js.map +1 -1
- package/dist/cf-worker/do/sqlite.d.ts.map +1 -1
- package/dist/cf-worker/do/sqlite.js.map +1 -1
- package/dist/cf-worker/do/sync-storage.d.ts +1 -1
- package/dist/cf-worker/do/sync-storage.d.ts.map +1 -1
- package/dist/cf-worker/do/sync-storage.js +2 -1
- package/dist/cf-worker/do/sync-storage.js.map +1 -1
- package/dist/cf-worker/do/transport/do-rpc-server.d.ts.map +1 -1
- package/dist/cf-worker/do/transport/do-rpc-server.js +9 -5
- package/dist/cf-worker/do/transport/do-rpc-server.js.map +1 -1
- package/dist/cf-worker/do/transport/http-rpc-server.d.ts +1 -1
- package/dist/cf-worker/do/transport/http-rpc-server.d.ts.map +1 -1
- package/dist/cf-worker/do/transport/http-rpc-server.js +2 -2
- package/dist/cf-worker/do/transport/http-rpc-server.js.map +1 -1
- package/dist/cf-worker/do/transport/ws-rpc-server.d.ts.map +1 -1
- package/dist/cf-worker/do/transport/ws-rpc-server.js +7 -3
- package/dist/cf-worker/do/transport/ws-rpc-server.js.map +1 -1
- package/dist/cf-worker/shared.d.ts +7 -7
- package/dist/cf-worker/shared.d.ts.map +1 -1
- package/dist/cf-worker/worker.d.ts.map +1 -1
- package/dist/cf-worker/worker.js +7 -7
- package/dist/cf-worker/worker.js.map +1 -1
- package/dist/client/transport/do-rpc-client.d.ts.map +1 -1
- package/dist/client/transport/do-rpc-client.js +11 -7
- package/dist/client/transport/do-rpc-client.js.map +1 -1
- package/dist/client/transport/http-rpc-client.d.ts.map +1 -1
- package/dist/client/transport/http-rpc-client.js +10 -6
- package/dist/client/transport/http-rpc-client.js.map +1 -1
- package/dist/client/transport/ws-rpc-client.d.ts.map +1 -1
- package/dist/client/transport/ws-rpc-client.js +11 -11
- package/dist/client/transport/ws-rpc-client.js.map +1 -1
- package/dist/common/do-rpc-schema.d.ts +3 -3
- package/dist/common/do-rpc-schema.d.ts.map +1 -1
- package/dist/common/do-rpc-schema.js +3 -3
- package/dist/common/do-rpc-schema.js.map +1 -1
- package/dist/common/http-rpc-schema.d.ts +3 -3
- package/dist/common/http-rpc-schema.d.ts.map +1 -1
- package/dist/common/http-rpc-schema.js +3 -3
- package/dist/common/http-rpc-schema.js.map +1 -1
- package/dist/common/sync-message-types.d.ts +2 -2
- package/dist/common/ws-rpc-schema.d.ts +3 -3
- package/dist/common/ws-rpc-schema.d.ts.map +1 -1
- package/dist/common/ws-rpc-schema.js +3 -3
- package/dist/common/ws-rpc-schema.js.map +1 -1
- package/package.json +71 -13
- package/src/cf-worker/do/durable-object.ts +10 -8
- package/src/cf-worker/do/layer.ts +4 -3
- package/src/cf-worker/do/pull.ts +17 -6
- package/src/cf-worker/do/push.ts +20 -9
- package/src/cf-worker/do/sqlite.ts +1 -0
- package/src/cf-worker/do/sync-storage.ts +4 -2
- package/src/cf-worker/do/transport/do-rpc-server.ts +14 -5
- package/src/cf-worker/do/transport/http-rpc-server.ts +17 -17
- package/src/cf-worker/do/transport/ws-rpc-server.ts +13 -4
- package/src/cf-worker/shared.ts +3 -3
- package/src/cf-worker/worker.ts +17 -14
- package/src/client/transport/do-rpc-client.ts +20 -14
- package/src/client/transport/http-rpc-client.ts +19 -13
- package/src/client/transport/ws-rpc-client.ts +39 -36
- package/src/common/do-rpc-schema.ts +4 -3
- package/src/common/http-rpc-schema.ts +4 -3
- package/src/common/ws-rpc-schema.ts +4 -3
package/src/cf-worker/worker.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { env as importedEnv } from 'cloudflare:workers'
|
|
2
|
+
|
|
2
3
|
import { UnknownError } from '@livestore/common'
|
|
3
4
|
import type { HelperTypes } from '@livestore/common-cf'
|
|
4
5
|
import { Effect, Schema } from '@livestore/utils/effect'
|
|
6
|
+
|
|
5
7
|
import type { CfTypes, SearchParams } from '../common/mod.ts'
|
|
6
8
|
import type { CfDeclare } from './mod.ts'
|
|
7
9
|
import { type Env, type ForwardedHeaders, matchSyncRequest } from './shared.ts'
|
|
@@ -80,15 +82,16 @@ export const makeWorker = <
|
|
|
80
82
|
fetch: async (request, env, _ctx) => {
|
|
81
83
|
const url = new URL(request.url)
|
|
82
84
|
|
|
83
|
-
const corsHeaders: CfTypes.HeadersInit =
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
85
|
+
const corsHeaders: CfTypes.HeadersInit =
|
|
86
|
+
options.enableCORS === true
|
|
87
|
+
? {
|
|
88
|
+
'Access-Control-Allow-Origin': '*',
|
|
89
|
+
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
|
90
|
+
'Access-Control-Allow-Headers': request.headers.get('Access-Control-Request-Headers') ?? '*',
|
|
91
|
+
}
|
|
92
|
+
: {}
|
|
90
93
|
|
|
91
|
-
if (request.method === 'OPTIONS' && options.enableCORS) {
|
|
94
|
+
if (request.method === 'OPTIONS' && options.enableCORS === true) {
|
|
92
95
|
return new Response(null, {
|
|
93
96
|
status: 204,
|
|
94
97
|
headers: corsHeaders,
|
|
@@ -202,16 +205,16 @@ export const handleSyncRequest = <
|
|
|
202
205
|
if (decodedEither._tag === 'Left') {
|
|
203
206
|
const message = decodedEither.left.toString()
|
|
204
207
|
console.error('Invalid payload (decode failed)', message)
|
|
205
|
-
return new Response(message, { status: 400, headers })
|
|
208
|
+
return new Response(message, { status: 400, ...(headers !== undefined ? { headers } : {}) })
|
|
206
209
|
}
|
|
207
210
|
|
|
208
211
|
const result = yield* Effect.promise(async () =>
|
|
209
|
-
validatePayload(decodedEither.right
|
|
212
|
+
validatePayload(decodedEither.right, { storeId, headers: requestHeaders }),
|
|
210
213
|
).pipe(UnknownError.mapToUnknownError, Effect.either)
|
|
211
214
|
|
|
212
215
|
if (result._tag === 'Left') {
|
|
213
216
|
console.error('Invalid payload (validation failed)', result.left)
|
|
214
|
-
return new Response(result.left.toString(), { status: 400, headers })
|
|
217
|
+
return new Response(result.left.toString(), { status: 400, ...(headers !== undefined ? { headers } : {}) })
|
|
215
218
|
}
|
|
216
219
|
} else {
|
|
217
220
|
const result = yield* Effect.promise(async () =>
|
|
@@ -220,7 +223,7 @@ export const handleSyncRequest = <
|
|
|
220
223
|
|
|
221
224
|
if (result._tag === 'Left') {
|
|
222
225
|
console.error('Invalid payload (validation failed)', result.left)
|
|
223
|
-
return new Response(result.left.toString(), { status: 400, headers })
|
|
226
|
+
return new Response(result.left.toString(), { status: 400, ...(headers !== undefined ? { headers } : {}) })
|
|
224
227
|
}
|
|
225
228
|
}
|
|
226
229
|
}
|
|
@@ -232,7 +235,7 @@ export const handleSyncRequest = <
|
|
|
232
235
|
`Failed dependency: Required Durable Object binding '${syncBackendBinding as string}' not available`,
|
|
233
236
|
{
|
|
234
237
|
status: 424,
|
|
235
|
-
headers,
|
|
238
|
+
...(headers !== undefined ? { headers } : {}),
|
|
236
239
|
},
|
|
237
240
|
)
|
|
238
241
|
}
|
|
@@ -249,7 +252,7 @@ export const handleSyncRequest = <
|
|
|
249
252
|
if (transport === 'ws' && (upgradeHeader === null || upgradeHeader !== 'websocket')) {
|
|
250
253
|
return new Response('Durable Object expected Upgrade: websocket', {
|
|
251
254
|
status: 426,
|
|
252
|
-
headers,
|
|
255
|
+
...(headers !== undefined ? { headers } : {}),
|
|
253
256
|
})
|
|
254
257
|
}
|
|
255
258
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SyncBackend, UnknownError } from '@livestore/common'
|
|
2
2
|
import { splitChunkBySize } from '@livestore/common/sync'
|
|
3
3
|
import { type CfTypes, layerProtocolDurableObject } from '@livestore/common-cf'
|
|
4
4
|
import { omit, shouldNeverHappen } from '@livestore/utils'
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
Stream,
|
|
16
16
|
SubscriptionRef,
|
|
17
17
|
} from '@livestore/utils/effect'
|
|
18
|
+
|
|
18
19
|
import type { SyncBackendRpcInterface } from '../../cf-worker/shared.ts'
|
|
19
20
|
import { MAX_DO_RPC_REQUEST_BYTES, MAX_PUSH_EVENTS_PER_REQUEST } from '../../common/constants.ts'
|
|
20
21
|
import { SyncDoRpc } from '../../common/do-rpc-schema.ts'
|
|
@@ -73,9 +74,9 @@ export const makeDoRpcSync =
|
|
|
73
74
|
})),
|
|
74
75
|
),
|
|
75
76
|
storeId,
|
|
76
|
-
rpcContext: options?.live ? { callerContext: durableObjectContext } : undefined,
|
|
77
|
+
rpcContext: options?.live === true ? { callerContext: durableObjectContext } : undefined,
|
|
77
78
|
}).pipe(
|
|
78
|
-
options?.live
|
|
79
|
+
options?.live === true
|
|
79
80
|
? Stream.concatWithLastElement((res) =>
|
|
80
81
|
Effect.gen(function* () {
|
|
81
82
|
if (res._tag === 'None')
|
|
@@ -93,12 +94,16 @@ export const makeDoRpcSync =
|
|
|
93
94
|
: identity,
|
|
94
95
|
Stream.tap((res) => backendIdHelper.lazySet(res.backendId)),
|
|
95
96
|
Stream.map((res) => omit(res, ['backendId'])),
|
|
96
|
-
Stream.mapError((cause) =>
|
|
97
|
+
Stream.mapError((cause) =>
|
|
98
|
+
cause._tag === 'UnknownError' || cause._tag === 'BackendIdMismatchError'
|
|
99
|
+
? cause
|
|
100
|
+
: new UnknownError({ cause }),
|
|
101
|
+
),
|
|
97
102
|
Stream.withSpan('rpc-sync-client:pull'),
|
|
98
103
|
)
|
|
99
104
|
|
|
100
|
-
const push: SyncBackend.SyncBackend<{ createdAt: string }>['push'] = (
|
|
101
|
-
|
|
105
|
+
const push: SyncBackend.SyncBackend<{ createdAt: string }>['push'] = Effect.fn('rpc-sync-client:push')(
|
|
106
|
+
function* (batch) {
|
|
102
107
|
if (batch.length === 0) {
|
|
103
108
|
return
|
|
104
109
|
}
|
|
@@ -114,19 +119,20 @@ export const makeDoRpcSync =
|
|
|
114
119
|
backendId,
|
|
115
120
|
}),
|
|
116
121
|
}),
|
|
117
|
-
Effect.mapError((cause) => new
|
|
122
|
+
Effect.mapError((cause) => new UnknownError({ cause })),
|
|
118
123
|
)
|
|
119
124
|
|
|
120
125
|
for (const chunk of Chunk.toReadonlyArray(batchChunks)) {
|
|
121
126
|
const chunkArray = Chunk.toReadonlyArray(chunk)
|
|
122
127
|
yield* rpcClient.SyncDoRpc.Push({ batch: chunkArray, storeId, backendId })
|
|
123
128
|
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
)
|
|
129
|
+
},
|
|
130
|
+
Effect.mapError((cause) =>
|
|
131
|
+
cause._tag === 'UnknownError' || cause._tag === 'ServerAheadError' || cause._tag === 'BackendIdMismatchError'
|
|
132
|
+
? cause
|
|
133
|
+
: new UnknownError({ cause }),
|
|
134
|
+
),
|
|
135
|
+
)
|
|
130
136
|
|
|
131
137
|
const ping: SyncBackend.SyncBackend<{ createdAt: string }>['ping'] = rpcClient.SyncDoRpc.Ping({
|
|
132
138
|
storeId,
|
|
@@ -170,7 +176,7 @@ export const makeDoRpcSync =
|
|
|
170
176
|
export const handleSyncUpdateRpc = (payload: unknown) =>
|
|
171
177
|
Effect.gen(function* () {
|
|
172
178
|
const decodedPayload = yield* Schema.decodeUnknown(ResponseChunkEncoded)(payload)
|
|
173
|
-
const decoded = yield* Schema.decodeUnknown(SyncMessage.PullResponse)(decodedPayload.values[0]
|
|
179
|
+
const decoded = yield* Schema.decodeUnknown(SyncMessage.PullResponse)(decodedPayload.values[0])
|
|
174
180
|
|
|
175
181
|
const pullStreamMailbox = requestIdMailboxMap.get(decodedPayload.requestId)
|
|
176
182
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SyncBackend, UnknownError } from '@livestore/common'
|
|
2
2
|
import type { EventSequenceNumber } from '@livestore/common/schema'
|
|
3
3
|
import { splitChunkBySize } from '@livestore/common/sync'
|
|
4
4
|
import { omit } from '@livestore/utils'
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
SubscriptionRef,
|
|
20
20
|
UrlParams,
|
|
21
21
|
} from '@livestore/utils/effect'
|
|
22
|
+
|
|
22
23
|
import { MAX_HTTP_REQUEST_BYTES, MAX_PUSH_EVENTS_PER_REQUEST } from '../../common/constants.ts'
|
|
23
24
|
import { SyncHttpRpc } from '../../common/http-rpc-schema.ts'
|
|
24
25
|
import { SearchParamsSchema } from '../../common/mod.ts'
|
|
@@ -134,7 +135,7 @@ export const makeHttpSync =
|
|
|
134
135
|
payload,
|
|
135
136
|
cursor: mapCursor(cursor),
|
|
136
137
|
}).pipe(
|
|
137
|
-
options?.live
|
|
138
|
+
options?.live === true
|
|
138
139
|
? // Phase 2: Simulate `live` pull by polling for new events
|
|
139
140
|
Stream.concatWithLastElement((lastElement) => {
|
|
140
141
|
const initialPhase2Cursor = lastElement.pipe(
|
|
@@ -166,14 +167,18 @@ export const makeHttpSync =
|
|
|
166
167
|
: identity,
|
|
167
168
|
Stream.tap((res) => backendIdHelper.lazySet(res.backendId)),
|
|
168
169
|
Stream.map((res) => omit(res, ['backendId'])),
|
|
169
|
-
Stream.mapError((cause) =>
|
|
170
|
+
Stream.mapError((cause) =>
|
|
171
|
+
cause._tag === 'UnknownError' || cause._tag === 'BackendIdMismatchError'
|
|
172
|
+
? cause
|
|
173
|
+
: new UnknownError({ cause }),
|
|
174
|
+
),
|
|
170
175
|
Stream.withSpan('http-sync-client:pull'),
|
|
171
176
|
)
|
|
172
177
|
|
|
173
178
|
const pushSemaphore = yield* Effect.makeSemaphore(1)
|
|
174
179
|
|
|
175
|
-
const push: SyncBackend.SyncBackend<SyncMetadata>['push'] = (
|
|
176
|
-
|
|
180
|
+
const push: SyncBackend.SyncBackend<SyncMetadata>['push'] = Effect.fn('http-sync-client:push')(
|
|
181
|
+
function* (batch) {
|
|
177
182
|
if (batch.length === 0) {
|
|
178
183
|
return
|
|
179
184
|
}
|
|
@@ -190,20 +195,21 @@ export const makeHttpSync =
|
|
|
190
195
|
backendId,
|
|
191
196
|
}),
|
|
192
197
|
}),
|
|
193
|
-
Effect.mapError((cause) => new
|
|
198
|
+
Effect.mapError((cause) => new UnknownError({ cause })),
|
|
194
199
|
)
|
|
195
200
|
|
|
196
201
|
for (const chunk of Chunk.toReadonlyArray(batchChunks)) {
|
|
197
202
|
const chunkArray = Chunk.toReadonlyArray(chunk)
|
|
198
203
|
yield* rpcClient.SyncHttpRpc.Push({ storeId, payload, batch: chunkArray, backendId })
|
|
199
204
|
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
)
|
|
205
|
+
},
|
|
206
|
+
pushSemaphore.withPermits(1),
|
|
207
|
+
Effect.mapError((cause) =>
|
|
208
|
+
cause._tag === 'UnknownError' || cause._tag === 'ServerAheadError' || cause._tag === 'BackendIdMismatchError'
|
|
209
|
+
? cause
|
|
210
|
+
: new UnknownError({ cause }),
|
|
211
|
+
),
|
|
212
|
+
)
|
|
207
213
|
|
|
208
214
|
return SyncBackend.of({
|
|
209
215
|
connect,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IsOfflineError, SyncBackend, UnknownError } from '@livestore/common'
|
|
2
2
|
import type { LiveStoreEvent } from '@livestore/common/schema'
|
|
3
3
|
import { splitChunkBySize } from '@livestore/common/sync'
|
|
4
4
|
import { omit } from '@livestore/utils'
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
UrlParams,
|
|
20
20
|
} from '@livestore/utils/effect'
|
|
21
21
|
import type { WebSocket } from '@livestore/utils/effect/browser'
|
|
22
|
+
|
|
22
23
|
import { MAX_PUSH_EVENTS_PER_REQUEST, MAX_WS_MESSAGE_BYTES } from '../../common/constants.ts'
|
|
23
24
|
import { SearchParamsSchema } from '../../common/mod.ts'
|
|
24
25
|
import type { SyncMetadata } from '../../common/sync-message-types.ts'
|
|
@@ -95,7 +96,10 @@ export const makeWsSync =
|
|
|
95
96
|
|
|
96
97
|
const ProtocolLive = RpcClient.layerProtocolSocketWithIsConnected({
|
|
97
98
|
isConnected,
|
|
98
|
-
retryTransientErrors: Schedule.
|
|
99
|
+
retryTransientErrors: Schedule.exponential('1 seconds').pipe(
|
|
100
|
+
Schedule.union(Schedule.fixed('30 seconds')),
|
|
101
|
+
Schedule.jittered,
|
|
102
|
+
),
|
|
99
103
|
pingSchedule: Schedule.once.pipe(Schedule.andThen(Schedule.fixed(pingInterval))),
|
|
100
104
|
url: wsUrl,
|
|
101
105
|
}).pipe(
|
|
@@ -138,55 +142,54 @@ export const makeWsSync =
|
|
|
138
142
|
backendId: backendIdHelper.get().pipe(Option.getOrThrow),
|
|
139
143
|
})),
|
|
140
144
|
),
|
|
141
|
-
live: options?.live
|
|
145
|
+
live: options?.live === true,
|
|
142
146
|
}).pipe(
|
|
143
147
|
Stream.tap((res) => backendIdHelper.lazySet(res.backendId)),
|
|
144
148
|
Stream.map((res) => omit(res, ['backendId'])),
|
|
145
149
|
Stream.mapError((cause) =>
|
|
146
|
-
cause._tag === 'RpcClientError' && Socket.isSocketError(cause.cause)
|
|
150
|
+
cause._tag === 'RpcClientError' && Socket.isSocketError(cause.cause) === true
|
|
147
151
|
? new IsOfflineError({ cause: cause.cause })
|
|
148
|
-
: cause._tag === '
|
|
152
|
+
: cause._tag === 'UnknownError' || cause._tag === 'BackendIdMismatchError'
|
|
149
153
|
? cause
|
|
150
|
-
:
|
|
154
|
+
: new UnknownError({ cause }),
|
|
151
155
|
),
|
|
152
156
|
Stream.withSpan('pull'),
|
|
153
157
|
),
|
|
154
158
|
|
|
155
|
-
push: (batch)
|
|
156
|
-
|
|
157
|
-
if (batch.length === 0) return
|
|
159
|
+
push: Effect.fn('push')(function* (batch) {
|
|
160
|
+
if (batch.length === 0) return
|
|
158
161
|
|
|
159
|
-
|
|
162
|
+
const encodePayload = (batch: ReadonlyArray<LiveStoreEvent.Global.Encoded>) => ({
|
|
163
|
+
storeId,
|
|
164
|
+
payload,
|
|
165
|
+
batch,
|
|
166
|
+
backendId: backendIdHelper.get(),
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
const chunksChunk = yield* Chunk.fromIterable(batch).pipe(
|
|
170
|
+
splitChunkBySize({
|
|
171
|
+
maxItems: MAX_PUSH_EVENTS_PER_REQUEST,
|
|
172
|
+
maxBytes: MAX_WS_MESSAGE_BYTES,
|
|
173
|
+
encode: encodePayload,
|
|
174
|
+
}),
|
|
175
|
+
Effect.mapError((cause) => new UnknownError({ cause })),
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
for (const sub of chunksChunk) {
|
|
179
|
+
yield* rpcClient.SyncWsRpc.Push({
|
|
160
180
|
storeId,
|
|
161
181
|
payload,
|
|
162
|
-
batch,
|
|
182
|
+
batch: Chunk.toReadonlyArray(sub),
|
|
163
183
|
backendId: backendIdHelper.get(),
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
encode: encodePayload,
|
|
171
|
-
}),
|
|
172
|
-
Effect.mapError((cause) => new InvalidPushError({ cause: new UnknownError({ cause }) })),
|
|
184
|
+
}).pipe(
|
|
185
|
+
Effect.mapError((cause) =>
|
|
186
|
+
cause._tag === 'UnknownError' || cause._tag === 'ServerAheadError' || cause._tag === 'BackendIdMismatchError'
|
|
187
|
+
? cause
|
|
188
|
+
: new UnknownError({ cause }),
|
|
189
|
+
),
|
|
173
190
|
)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
yield* rpcClient.SyncWsRpc.Push({
|
|
177
|
-
storeId,
|
|
178
|
-
payload,
|
|
179
|
-
batch: Chunk.toReadonlyArray(sub),
|
|
180
|
-
backendId: backendIdHelper.get(),
|
|
181
|
-
}).pipe(
|
|
182
|
-
Effect.mapError((cause) =>
|
|
183
|
-
cause._tag === 'InvalidPushError'
|
|
184
|
-
? cause
|
|
185
|
-
: new InvalidPushError({ cause: new UnknownError({ cause }) }),
|
|
186
|
-
),
|
|
187
|
-
)
|
|
188
|
-
}
|
|
189
|
-
}).pipe(Effect.withSpan('push')),
|
|
191
|
+
}
|
|
192
|
+
}),
|
|
190
193
|
ping,
|
|
191
194
|
metadata: {
|
|
192
195
|
name: '@livestore/cf-sync',
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BackendIdMismatchError, ServerAheadError, UnknownError } from '@livestore/common'
|
|
2
2
|
import { Rpc, RpcGroup, Schema } from '@livestore/utils/effect'
|
|
3
|
+
|
|
3
4
|
import * as SyncMessage from './sync-message-types.ts'
|
|
4
5
|
|
|
5
6
|
const commonPayloadFields = {
|
|
@@ -34,7 +35,7 @@ export class SyncDoRpc extends RpcGroup.make(
|
|
|
34
35
|
rpcRequestId: Schema.String,
|
|
35
36
|
...SyncMessage.PullResponse.fields,
|
|
36
37
|
}),
|
|
37
|
-
error:
|
|
38
|
+
error: Schema.Union(UnknownError, BackendIdMismatchError),
|
|
38
39
|
stream: true,
|
|
39
40
|
}),
|
|
40
41
|
Rpc.make('SyncDoRpc.Push', {
|
|
@@ -43,7 +44,7 @@ export class SyncDoRpc extends RpcGroup.make(
|
|
|
43
44
|
...commonPayloadFields,
|
|
44
45
|
},
|
|
45
46
|
success: SyncMessage.PushAck,
|
|
46
|
-
error:
|
|
47
|
+
error: Schema.Union(UnknownError, ServerAheadError, BackendIdMismatchError),
|
|
47
48
|
}),
|
|
48
49
|
Rpc.make('SyncDoRpc.Ping', {
|
|
49
50
|
payload: {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BackendIdMismatchError, ServerAheadError, UnknownError } from '@livestore/common'
|
|
2
2
|
import { Rpc, RpcGroup, Schema } from '@livestore/utils/effect'
|
|
3
|
+
|
|
3
4
|
import * as SyncMessage from './sync-message-types.ts'
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -17,7 +18,7 @@ export class SyncHttpRpc extends RpcGroup.make(
|
|
|
17
18
|
...SyncMessage.PullRequest.fields,
|
|
18
19
|
}),
|
|
19
20
|
success: SyncMessage.PullResponse,
|
|
20
|
-
error:
|
|
21
|
+
error: Schema.Union(UnknownError, BackendIdMismatchError),
|
|
21
22
|
stream: true,
|
|
22
23
|
}),
|
|
23
24
|
Rpc.make('SyncHttpRpc.Push', {
|
|
@@ -27,7 +28,7 @@ export class SyncHttpRpc extends RpcGroup.make(
|
|
|
27
28
|
...SyncMessage.PushRequest.fields,
|
|
28
29
|
}),
|
|
29
30
|
success: SyncMessage.PushAck,
|
|
30
|
-
error:
|
|
31
|
+
error: Schema.Union(UnknownError, ServerAheadError, BackendIdMismatchError),
|
|
31
32
|
}),
|
|
32
33
|
Rpc.make('SyncHttpRpc.Ping', {
|
|
33
34
|
payload: Schema.Struct({
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BackendIdMismatchError, ServerAheadError, UnknownError } from '@livestore/common'
|
|
2
2
|
import { Rpc, RpcGroup, Schema } from '@livestore/utils/effect'
|
|
3
|
+
|
|
3
4
|
import * as SyncMessage from './sync-message-types.ts'
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -19,7 +20,7 @@ export class SyncWsRpc extends RpcGroup.make(
|
|
|
19
20
|
...SyncMessage.PullRequest.fields,
|
|
20
21
|
}),
|
|
21
22
|
success: SyncMessage.PullResponse,
|
|
22
|
-
error:
|
|
23
|
+
error: Schema.Union(UnknownError, BackendIdMismatchError),
|
|
23
24
|
stream: true,
|
|
24
25
|
}),
|
|
25
26
|
Rpc.make('SyncWsRpc.Push', {
|
|
@@ -29,7 +30,7 @@ export class SyncWsRpc extends RpcGroup.make(
|
|
|
29
30
|
...SyncMessage.PushRequest.fields,
|
|
30
31
|
}),
|
|
31
32
|
success: SyncMessage.PushAck,
|
|
32
|
-
error:
|
|
33
|
+
error: Schema.Union(UnknownError, ServerAheadError, BackendIdMismatchError),
|
|
33
34
|
}),
|
|
34
35
|
// Ping <> Pong is handled by DO WS auto-response
|
|
35
36
|
// TODO add admin RPCs
|