@livestore/sync-s2 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/dist/.tsbuildinfo +1 -1
- package/dist/api-schema.d.ts.map +1 -1
- package/dist/api-schema.js.map +1 -1
- package/dist/api-schema.test.js +1 -1
- package/dist/api-schema.test.js.map +1 -1
- package/dist/decode.d.ts.map +1 -1
- package/dist/decode.js.map +1 -1
- package/dist/http-client-generated.d.ts +22 -22
- package/dist/http-client-generated.d.ts.map +1 -1
- package/dist/http-client-generated.js +64 -22
- package/dist/http-client-generated.js.map +1 -1
- package/dist/limits.js +2 -2
- package/dist/limits.js.map +1 -1
- package/dist/limits.test.js.map +1 -1
- package/dist/make-s2-url.d.ts.map +1 -1
- package/dist/make-s2-url.js.map +1 -1
- package/dist/s2-proxy-helpers.d.ts +10 -2
- package/dist/s2-proxy-helpers.d.ts.map +1 -1
- package/dist/s2-proxy-helpers.js +16 -10
- package/dist/s2-proxy-helpers.js.map +1 -1
- package/dist/sync-provider.d.ts +4 -4
- package/dist/sync-provider.d.ts.map +1 -1
- package/dist/sync-provider.js +31 -31
- package/dist/sync-provider.js.map +1 -1
- package/package.json +76 -13
- package/src/api-schema.test.ts +3 -1
- package/src/api-schema.ts +1 -0
- package/src/decode.ts +1 -0
- package/src/http-client-generated.ts +74 -53
- package/src/limits.test.ts +3 -1
- package/src/limits.ts +2 -2
- package/src/make-s2-url.ts +1 -0
- package/src/s2-proxy-helpers.ts +27 -10
- package/src/sync-provider.ts +45 -37
|
@@ -677,7 +677,7 @@ export const make = (
|
|
|
677
677
|
)
|
|
678
678
|
const withResponse: <A, E>(
|
|
679
679
|
f: (response: HttpClientResponse.HttpClientResponse) => Effect.Effect<A, E>,
|
|
680
|
-
) => (request: HttpClientRequest.HttpClientRequest) => Effect.Effect<any, any> = options.transformClient
|
|
680
|
+
) => (request: HttpClientRequest.HttpClientRequest) => Effect.Effect<any, any> = options.transformClient !== undefined
|
|
681
681
|
? (f) => (request) =>
|
|
682
682
|
Effect.flatMap(
|
|
683
683
|
Effect.flatMap(options.transformClient!(httpClient), (client) => client.execute(request)),
|
|
@@ -697,6 +697,7 @@ export const make = (
|
|
|
697
697
|
return {
|
|
698
698
|
httpClient,
|
|
699
699
|
listAccessTokens: (options) =>
|
|
700
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
700
701
|
HttpClientRequest.get(`/access-tokens`).pipe(
|
|
701
702
|
HttpClientRequest.setUrlParams({
|
|
702
703
|
prefix: options?.prefix as any,
|
|
@@ -713,6 +714,7 @@ export const make = (
|
|
|
713
714
|
),
|
|
714
715
|
),
|
|
715
716
|
issueAccessToken: (options) =>
|
|
717
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
716
718
|
HttpClientRequest.post(`/access-tokens`).pipe(
|
|
717
719
|
HttpClientRequest.bodyUnsafeJson(options),
|
|
718
720
|
withResponse(
|
|
@@ -726,6 +728,7 @@ export const make = (
|
|
|
726
728
|
),
|
|
727
729
|
),
|
|
728
730
|
revokeAccessToken: (id) =>
|
|
731
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
729
732
|
HttpClientRequest.del(`/access-tokens/${id}`).pipe(
|
|
730
733
|
withResponse(
|
|
731
734
|
HttpClientResponse.matchStatus({
|
|
@@ -737,6 +740,7 @@ export const make = (
|
|
|
737
740
|
),
|
|
738
741
|
),
|
|
739
742
|
listBasins: (options) =>
|
|
743
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
740
744
|
HttpClientRequest.get(`/basins`).pipe(
|
|
741
745
|
HttpClientRequest.setUrlParams({
|
|
742
746
|
prefix: options?.prefix as any,
|
|
@@ -753,6 +757,7 @@ export const make = (
|
|
|
753
757
|
),
|
|
754
758
|
),
|
|
755
759
|
createBasin: (options) =>
|
|
760
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
756
761
|
HttpClientRequest.post(`/basins`).pipe(
|
|
757
762
|
HttpClientRequest.bodyUnsafeJson(options),
|
|
758
763
|
withResponse(
|
|
@@ -768,6 +773,7 @@ export const make = (
|
|
|
768
773
|
),
|
|
769
774
|
),
|
|
770
775
|
getBasinConfig: (basin) =>
|
|
776
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
771
777
|
HttpClientRequest.get(`/basins/${basin}`).pipe(
|
|
772
778
|
withResponse(
|
|
773
779
|
HttpClientResponse.matchStatus({
|
|
@@ -780,6 +786,7 @@ export const make = (
|
|
|
780
786
|
),
|
|
781
787
|
),
|
|
782
788
|
createOrReconfigureBasin: (basin, options) =>
|
|
789
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
783
790
|
HttpClientRequest.put(`/basins/${basin}`).pipe(
|
|
784
791
|
HttpClientRequest.setHeaders({ 's2-request-token': options.params?.['s2-request-token'] ?? undefined }),
|
|
785
792
|
HttpClientRequest.bodyUnsafeJson(options.payload),
|
|
@@ -794,6 +801,7 @@ export const make = (
|
|
|
794
801
|
),
|
|
795
802
|
),
|
|
796
803
|
deleteBasin: (basin) =>
|
|
804
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
797
805
|
HttpClientRequest.del(`/basins/${basin}`).pipe(
|
|
798
806
|
withResponse(
|
|
799
807
|
HttpClientResponse.matchStatus({
|
|
@@ -807,6 +815,7 @@ export const make = (
|
|
|
807
815
|
),
|
|
808
816
|
),
|
|
809
817
|
reconfigureBasin: (basin, options) =>
|
|
818
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
810
819
|
HttpClientRequest.patch(`/basins/${basin}`).pipe(
|
|
811
820
|
HttpClientRequest.bodyUnsafeJson(options),
|
|
812
821
|
withResponse(
|
|
@@ -820,6 +829,7 @@ export const make = (
|
|
|
820
829
|
),
|
|
821
830
|
),
|
|
822
831
|
accountMetrics: (options) =>
|
|
832
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
823
833
|
HttpClientRequest.get(`/metrics`).pipe(
|
|
824
834
|
HttpClientRequest.setUrlParams({
|
|
825
835
|
set: options?.set as any,
|
|
@@ -837,6 +847,7 @@ export const make = (
|
|
|
837
847
|
),
|
|
838
848
|
),
|
|
839
849
|
basinMetrics: (basin, options) =>
|
|
850
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
840
851
|
HttpClientRequest.get(`/metrics/${basin}`).pipe(
|
|
841
852
|
HttpClientRequest.setUrlParams({
|
|
842
853
|
set: options?.set as any,
|
|
@@ -854,6 +865,7 @@ export const make = (
|
|
|
854
865
|
),
|
|
855
866
|
),
|
|
856
867
|
streamMetrics: (basin, stream, options) =>
|
|
868
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
857
869
|
HttpClientRequest.get(`/metrics/${basin}/${stream}`).pipe(
|
|
858
870
|
HttpClientRequest.setUrlParams({
|
|
859
871
|
set: options?.set as any,
|
|
@@ -871,6 +883,7 @@ export const make = (
|
|
|
871
883
|
),
|
|
872
884
|
),
|
|
873
885
|
listStreams: (options) =>
|
|
886
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
874
887
|
HttpClientRequest.get(`/streams`).pipe(
|
|
875
888
|
HttpClientRequest.setUrlParams({
|
|
876
889
|
prefix: options?.prefix as any,
|
|
@@ -888,6 +901,7 @@ export const make = (
|
|
|
888
901
|
),
|
|
889
902
|
),
|
|
890
903
|
createStream: (options) =>
|
|
904
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
891
905
|
HttpClientRequest.post(`/streams`).pipe(
|
|
892
906
|
HttpClientRequest.bodyUnsafeJson(options),
|
|
893
907
|
withResponse(
|
|
@@ -902,6 +916,7 @@ export const make = (
|
|
|
902
916
|
),
|
|
903
917
|
),
|
|
904
918
|
getStreamConfig: (stream) =>
|
|
919
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
905
920
|
HttpClientRequest.get(`/streams/${stream}`).pipe(
|
|
906
921
|
withResponse(
|
|
907
922
|
HttpClientResponse.matchStatus({
|
|
@@ -915,6 +930,7 @@ export const make = (
|
|
|
915
930
|
),
|
|
916
931
|
),
|
|
917
932
|
createOrReconfigureStream: (stream, options) =>
|
|
933
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
918
934
|
HttpClientRequest.put(`/streams/${stream}`).pipe(
|
|
919
935
|
HttpClientRequest.setHeaders({ 's2-request-token': options.params?.['s2-request-token'] ?? undefined }),
|
|
920
936
|
HttpClientRequest.bodyUnsafeJson(options.payload),
|
|
@@ -931,6 +947,7 @@ export const make = (
|
|
|
931
947
|
),
|
|
932
948
|
),
|
|
933
949
|
deleteStream: (stream) =>
|
|
950
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
934
951
|
HttpClientRequest.del(`/streams/${stream}`).pipe(
|
|
935
952
|
withResponse(
|
|
936
953
|
HttpClientResponse.matchStatus({
|
|
@@ -943,6 +960,7 @@ export const make = (
|
|
|
943
960
|
),
|
|
944
961
|
),
|
|
945
962
|
reconfigureStream: (stream, options) =>
|
|
963
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
946
964
|
HttpClientRequest.patch(`/streams/${stream}`).pipe(
|
|
947
965
|
HttpClientRequest.bodyUnsafeJson(options),
|
|
948
966
|
withResponse(
|
|
@@ -957,6 +975,7 @@ export const make = (
|
|
|
957
975
|
),
|
|
958
976
|
),
|
|
959
977
|
read: (stream, options) =>
|
|
978
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
960
979
|
HttpClientRequest.get(`/streams/${stream}/records`).pipe(
|
|
961
980
|
HttpClientRequest.setUrlParams({
|
|
962
981
|
seq_num: options?.seq_num as any,
|
|
@@ -982,6 +1001,7 @@ export const make = (
|
|
|
982
1001
|
),
|
|
983
1002
|
),
|
|
984
1003
|
append: (stream, options) =>
|
|
1004
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
985
1005
|
HttpClientRequest.post(`/streams/${stream}/records`).pipe(
|
|
986
1006
|
HttpClientRequest.setHeaders({ 's2-format': options.params?.['s2-format'] ?? undefined }),
|
|
987
1007
|
HttpClientRequest.bodyUnsafeJson(options.payload),
|
|
@@ -999,6 +1019,7 @@ export const make = (
|
|
|
999
1019
|
),
|
|
1000
1020
|
),
|
|
1001
1021
|
checkTail: (stream) =>
|
|
1022
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off
|
|
1002
1023
|
HttpClientRequest.get(`/streams/${stream}/records/tail`).pipe(
|
|
1003
1024
|
withResponse(
|
|
1004
1025
|
HttpClientResponse.matchStatus({
|
|
@@ -1021,13 +1042,13 @@ export interface Client {
|
|
|
1021
1042
|
* List access tokens.
|
|
1022
1043
|
*/
|
|
1023
1044
|
readonly listAccessTokens: (
|
|
1024
|
-
options?: typeof ListAccessTokensParams.Encoded
|
|
1045
|
+
options?: typeof ListAccessTokensParams.Encoded ,
|
|
1025
1046
|
) => Effect.Effect<
|
|
1026
1047
|
typeof ListAccessTokensResponse.Type,
|
|
1027
1048
|
| HttpClientError.HttpClientError
|
|
1028
1049
|
| ParseResult.ParseError
|
|
1029
1050
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1030
|
-
|
|
1051
|
+
|
|
1031
1052
|
>
|
|
1032
1053
|
/**
|
|
1033
1054
|
* Issue a new access token.
|
|
@@ -1039,8 +1060,8 @@ export interface Client {
|
|
|
1039
1060
|
| HttpClientError.HttpClientError
|
|
1040
1061
|
| ParseResult.ParseError
|
|
1041
1062
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1042
|
-
|
|
1043
|
-
|
|
1063
|
+
|
|
1064
|
+
|
|
1044
1065
|
>
|
|
1045
1066
|
/**
|
|
1046
1067
|
* Revoke an access token.
|
|
@@ -1052,19 +1073,19 @@ export interface Client {
|
|
|
1052
1073
|
| HttpClientError.HttpClientError
|
|
1053
1074
|
| ParseResult.ParseError
|
|
1054
1075
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1055
|
-
|
|
1076
|
+
|
|
1056
1077
|
>
|
|
1057
1078
|
/**
|
|
1058
1079
|
* List basins.
|
|
1059
1080
|
*/
|
|
1060
1081
|
readonly listBasins: (
|
|
1061
|
-
options?: typeof ListBasinsParams.Encoded
|
|
1082
|
+
options?: typeof ListBasinsParams.Encoded ,
|
|
1062
1083
|
) => Effect.Effect<
|
|
1063
1084
|
typeof ListBasinsResponse.Type,
|
|
1064
1085
|
| HttpClientError.HttpClientError
|
|
1065
1086
|
| ParseResult.ParseError
|
|
1066
1087
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1067
|
-
|
|
1088
|
+
|
|
1068
1089
|
>
|
|
1069
1090
|
/**
|
|
1070
1091
|
* Create a basin.
|
|
@@ -1072,13 +1093,13 @@ export interface Client {
|
|
|
1072
1093
|
readonly createBasin: (
|
|
1073
1094
|
options: typeof CreateBasinRequest.Encoded,
|
|
1074
1095
|
) => Effect.Effect<
|
|
1075
|
-
typeof BasinInfo.Type
|
|
1096
|
+
typeof BasinInfo.Type ,
|
|
1076
1097
|
| HttpClientError.HttpClientError
|
|
1077
1098
|
| ParseResult.ParseError
|
|
1078
1099
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1100
|
+
|
|
1101
|
+
|
|
1102
|
+
|
|
1082
1103
|
>
|
|
1083
1104
|
/**
|
|
1084
1105
|
* Get basin configuration.
|
|
@@ -1090,8 +1111,8 @@ export interface Client {
|
|
|
1090
1111
|
| HttpClientError.HttpClientError
|
|
1091
1112
|
| ParseResult.ParseError
|
|
1092
1113
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1093
|
-
|
|
1094
|
-
|
|
1114
|
+
|
|
1115
|
+
|
|
1095
1116
|
>
|
|
1096
1117
|
/**
|
|
1097
1118
|
* Create or reconfigure a basin.
|
|
@@ -1103,7 +1124,7 @@ export interface Client {
|
|
|
1103
1124
|
readonly payload: typeof CreateOrReconfigureBasinRequest.Encoded
|
|
1104
1125
|
},
|
|
1105
1126
|
) => Effect.Effect<
|
|
1106
|
-
typeof BasinInfo.Type
|
|
1127
|
+
typeof BasinInfo.Type ,
|
|
1107
1128
|
HttpClientError.HttpClientError | ParseResult.ParseError | ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1108
1129
|
>
|
|
1109
1130
|
/**
|
|
@@ -1116,9 +1137,9 @@ export interface Client {
|
|
|
1116
1137
|
| HttpClientError.HttpClientError
|
|
1117
1138
|
| ParseResult.ParseError
|
|
1118
1139
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1140
|
+
|
|
1141
|
+
|
|
1142
|
+
|
|
1122
1143
|
>
|
|
1123
1144
|
/**
|
|
1124
1145
|
* Reconfigure a basin.
|
|
@@ -1131,8 +1152,8 @@ export interface Client {
|
|
|
1131
1152
|
| HttpClientError.HttpClientError
|
|
1132
1153
|
| ParseResult.ParseError
|
|
1133
1154
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1134
|
-
|
|
1135
|
-
|
|
1155
|
+
|
|
1156
|
+
|
|
1136
1157
|
>
|
|
1137
1158
|
/**
|
|
1138
1159
|
* Account-level metrics.
|
|
@@ -1144,7 +1165,7 @@ export interface Client {
|
|
|
1144
1165
|
| HttpClientError.HttpClientError
|
|
1145
1166
|
| ParseResult.ParseError
|
|
1146
1167
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1147
|
-
|
|
1168
|
+
|
|
1148
1169
|
>
|
|
1149
1170
|
/**
|
|
1150
1171
|
* Basin-level metrics.
|
|
@@ -1157,7 +1178,7 @@ export interface Client {
|
|
|
1157
1178
|
| HttpClientError.HttpClientError
|
|
1158
1179
|
| ParseResult.ParseError
|
|
1159
1180
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1160
|
-
|
|
1181
|
+
|
|
1161
1182
|
>
|
|
1162
1183
|
/**
|
|
1163
1184
|
* Stream-level metrics.
|
|
@@ -1171,20 +1192,20 @@ export interface Client {
|
|
|
1171
1192
|
| HttpClientError.HttpClientError
|
|
1172
1193
|
| ParseResult.ParseError
|
|
1173
1194
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1174
|
-
|
|
1195
|
+
|
|
1175
1196
|
>
|
|
1176
1197
|
/**
|
|
1177
1198
|
* List streams.
|
|
1178
1199
|
*/
|
|
1179
1200
|
readonly listStreams: (
|
|
1180
|
-
options?: typeof ListStreamsParams.Encoded
|
|
1201
|
+
options?: typeof ListStreamsParams.Encoded ,
|
|
1181
1202
|
) => Effect.Effect<
|
|
1182
1203
|
typeof ListStreamsResponse.Type,
|
|
1183
1204
|
| HttpClientError.HttpClientError
|
|
1184
1205
|
| ParseResult.ParseError
|
|
1185
1206
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1186
|
-
|
|
1187
|
-
|
|
1207
|
+
|
|
1208
|
+
|
|
1188
1209
|
>
|
|
1189
1210
|
/**
|
|
1190
1211
|
* Create a stream.
|
|
@@ -1196,9 +1217,9 @@ export interface Client {
|
|
|
1196
1217
|
| HttpClientError.HttpClientError
|
|
1197
1218
|
| ParseResult.ParseError
|
|
1198
1219
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1220
|
+
|
|
1221
|
+
|
|
1222
|
+
|
|
1202
1223
|
>
|
|
1203
1224
|
/**
|
|
1204
1225
|
* Get stream configuration.
|
|
@@ -1210,9 +1231,9 @@ export interface Client {
|
|
|
1210
1231
|
| HttpClientError.HttpClientError
|
|
1211
1232
|
| ParseResult.ParseError
|
|
1212
1233
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
|
|
1216
1237
|
>
|
|
1217
1238
|
/**
|
|
1218
1239
|
* Create or reconfigure a stream.
|
|
@@ -1228,9 +1249,9 @@ export interface Client {
|
|
|
1228
1249
|
| HttpClientError.HttpClientError
|
|
1229
1250
|
| ParseResult.ParseError
|
|
1230
1251
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1252
|
+
|
|
1253
|
+
|
|
1254
|
+
|
|
1234
1255
|
>
|
|
1235
1256
|
/**
|
|
1236
1257
|
* Delete a stream.
|
|
@@ -1242,8 +1263,8 @@ export interface Client {
|
|
|
1242
1263
|
| HttpClientError.HttpClientError
|
|
1243
1264
|
| ParseResult.ParseError
|
|
1244
1265
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1245
|
-
|
|
1246
|
-
|
|
1266
|
+
|
|
1267
|
+
|
|
1247
1268
|
>
|
|
1248
1269
|
/**
|
|
1249
1270
|
* Reconfigure a stream.
|
|
@@ -1256,26 +1277,26 @@ export interface Client {
|
|
|
1256
1277
|
| HttpClientError.HttpClientError
|
|
1257
1278
|
| ParseResult.ParseError
|
|
1258
1279
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1280
|
+
|
|
1281
|
+
|
|
1282
|
+
|
|
1262
1283
|
>
|
|
1263
1284
|
/**
|
|
1264
1285
|
* Read records.
|
|
1265
1286
|
*/
|
|
1266
1287
|
readonly read: (
|
|
1267
1288
|
stream: string,
|
|
1268
|
-
options?: typeof ReadParams.Encoded
|
|
1289
|
+
options?: typeof ReadParams.Encoded ,
|
|
1269
1290
|
) => Effect.Effect<
|
|
1270
1291
|
typeof ReadBatch.Type,
|
|
1271
1292
|
| HttpClientError.HttpClientError
|
|
1272
1293
|
| ParseResult.ParseError
|
|
1273
1294
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1295
|
+
|
|
1296
|
+
|
|
1297
|
+
|
|
1277
1298
|
| ClientError<'TailResponse', typeof TailResponse.Type>
|
|
1278
|
-
|
|
1299
|
+
|
|
1279
1300
|
>
|
|
1280
1301
|
/**
|
|
1281
1302
|
* Append records.
|
|
@@ -1291,11 +1312,11 @@ export interface Client {
|
|
|
1291
1312
|
| HttpClientError.HttpClientError
|
|
1292
1313
|
| ParseResult.ParseError
|
|
1293
1314
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
|
|
1297
1318
|
| ClientError<'AppendConditionFailed', typeof AppendConditionFailed.Type>
|
|
1298
|
-
|
|
1319
|
+
|
|
1299
1320
|
>
|
|
1300
1321
|
/**
|
|
1301
1322
|
* Check the tail.
|
|
@@ -1307,10 +1328,10 @@ export interface Client {
|
|
|
1307
1328
|
| HttpClientError.HttpClientError
|
|
1308
1329
|
| ParseResult.ParseError
|
|
1309
1330
|
| ClientError<'ErrorResponse', typeof ErrorResponse.Type>
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1331
|
+
|
|
1332
|
+
|
|
1333
|
+
|
|
1334
|
+
|
|
1314
1335
|
>
|
|
1315
1336
|
}
|
|
1316
1337
|
|
package/src/limits.test.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import type { EventSequenceNumber, LiveStoreEvent } from '@livestore/common/schema'
|
|
2
1
|
import { describe, expect, it } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import type { EventSequenceNumber, LiveStoreEvent } from '@livestore/common/schema'
|
|
4
|
+
|
|
3
5
|
import {
|
|
4
6
|
chunkEventsForS2,
|
|
5
7
|
computeRecordMeteredBytes,
|
package/src/limits.ts
CHANGED
|
@@ -21,7 +21,7 @@ export const MAX_RECORDS_PER_BATCH = 1_000
|
|
|
21
21
|
|
|
22
22
|
const LimitType = Schema.Literal('record-metered-bytes', 'batch-metered-bytes', 'batch-count')
|
|
23
23
|
|
|
24
|
-
export class S2LimitExceededError extends Schema.TaggedError<S2LimitExceededError>()('S2LimitExceededError', {
|
|
24
|
+
export class S2LimitExceededError extends Schema.TaggedError<S2LimitExceededError>('~@livestore/sync-s2/S2LimitExceededError')('S2LimitExceededError', {
|
|
25
25
|
limitType: LimitType,
|
|
26
26
|
max: Schema.Number,
|
|
27
27
|
actual: Schema.Number,
|
|
@@ -121,7 +121,7 @@ export const chunkEventsForS2 = (events: ReadonlyArray<LiveStoreEvent.Global.Enc
|
|
|
121
121
|
|
|
122
122
|
return mapPreparedChunks(chunks)
|
|
123
123
|
} catch (error) {
|
|
124
|
-
if (error && typeof error === 'object' && (error as any)._tag === 'OversizeChunkItemError') {
|
|
124
|
+
if (error !== undefined && typeof error === 'object' && (error as any)._tag === 'OversizeChunkItemError') {
|
|
125
125
|
const oversize = error as { size: number; maxBytes: number; _tag: string }
|
|
126
126
|
throw new S2LimitExceededError({
|
|
127
127
|
limitType: 'record-metered-bytes',
|
package/src/make-s2-url.ts
CHANGED
package/src/s2-proxy-helpers.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { LiveStoreEvent } from '@livestore/livestore'
|
|
7
|
+
|
|
7
8
|
import type { PullArgs } from './api-schema.ts'
|
|
8
9
|
import { chunkEventsForS2 } from './limits.ts'
|
|
9
10
|
import { makeS2StreamName } from './make-s2-url.ts'
|
|
@@ -16,8 +17,20 @@ export interface S2Config {
|
|
|
16
17
|
accountBase?: string
|
|
17
18
|
/** @default 'https://{basin}.b.aws.s2.dev/v1' */
|
|
18
19
|
basinBase?: string
|
|
20
|
+
/**
|
|
21
|
+
* When true, adds `S2-Basin` header to requests. This is required for s2-lite
|
|
22
|
+
* (the open-source self-hosted S2) which uses header-based basin routing instead
|
|
23
|
+
* of subdomain-based routing used by hosted S2.
|
|
24
|
+
* @see https://github.com/s2-streamstore/s2-lite
|
|
25
|
+
*/
|
|
26
|
+
lite?: boolean
|
|
19
27
|
}
|
|
20
28
|
|
|
29
|
+
export const isLiteMode = (config: S2Config): boolean => config.lite === true
|
|
30
|
+
|
|
31
|
+
const getBasinHeader = (config: S2Config): Record<string, string> =>
|
|
32
|
+
isLiteMode(config) === true ? { 's2-basin': config.basin } : {}
|
|
33
|
+
|
|
21
34
|
// URL construction helpers
|
|
22
35
|
export const getBasinUrl = (config: S2Config, path: string): string => {
|
|
23
36
|
const base = config.basinBase ?? `https://${config.basin}.b.aws.s2.dev/v1`
|
|
@@ -35,7 +48,7 @@ export const getStreamRecordsUrl = (
|
|
|
35
48
|
params?: { seq_num?: number; count?: number; clamp?: boolean; wait?: number },
|
|
36
49
|
): string => {
|
|
37
50
|
const base = getBasinUrl(config, `/streams/${encodeURIComponent(stream)}/records`)
|
|
38
|
-
if (
|
|
51
|
+
if (params == null) return base
|
|
39
52
|
|
|
40
53
|
const searchParams = new URLSearchParams()
|
|
41
54
|
/** seq_num - The sequence number to start from. See: https://docs.s2.dev/api#seq_num */
|
|
@@ -47,7 +60,8 @@ export const getStreamRecordsUrl = (
|
|
|
47
60
|
/** wait - How long to wait for new records before returning. See: https://docs.s2.dev/api#wait */
|
|
48
61
|
if (params.wait !== undefined) searchParams.append('wait', params.wait.toString())
|
|
49
62
|
|
|
50
|
-
|
|
63
|
+
const searchParamsString = searchParams.toString()
|
|
64
|
+
return searchParamsString.length > 0 ? `${base}?${searchParams}` : base
|
|
51
65
|
}
|
|
52
66
|
|
|
53
67
|
// Header helpers
|
|
@@ -55,14 +69,16 @@ export const getAuthHeaders = (token: string): Record<string, string> => ({
|
|
|
55
69
|
Authorization: `Bearer ${token}`,
|
|
56
70
|
})
|
|
57
71
|
|
|
58
|
-
export const getSSEHeaders = (
|
|
59
|
-
...getAuthHeaders(token),
|
|
72
|
+
export const getSSEHeaders = (config: S2Config): Record<string, string> => ({
|
|
73
|
+
...getAuthHeaders(config.token),
|
|
74
|
+
...getBasinHeader(config),
|
|
60
75
|
accept: 'text/event-stream',
|
|
61
76
|
's2-format': 'raw',
|
|
62
77
|
})
|
|
63
78
|
|
|
64
|
-
export const getPushHeaders = (
|
|
65
|
-
...getAuthHeaders(token),
|
|
79
|
+
export const getPushHeaders = (config: S2Config): Record<string, string> => ({
|
|
80
|
+
...getAuthHeaders(config.token),
|
|
81
|
+
...getBasinHeader(config),
|
|
66
82
|
'content-type': 'application/json',
|
|
67
83
|
's2-format': 'raw',
|
|
68
84
|
})
|
|
@@ -89,6 +105,7 @@ export const ensureStream = async (config: S2Config, stream: string): Promise<vo
|
|
|
89
105
|
method: 'POST',
|
|
90
106
|
headers: {
|
|
91
107
|
...getAuthHeaders(config.token),
|
|
108
|
+
...getBasinHeader(config),
|
|
92
109
|
'content-type': 'application/json',
|
|
93
110
|
},
|
|
94
111
|
body: JSON.stringify({ stream }),
|
|
@@ -114,15 +131,15 @@ export const buildPullRequest = ({
|
|
|
114
131
|
// cursor points to last processed record, seq_num needs to be the next record
|
|
115
132
|
const seq_num = args.s2SeqNum === 'from-start' ? 0 : args.s2SeqNum + 1
|
|
116
133
|
|
|
117
|
-
if (args.live) {
|
|
134
|
+
if (args.live === true) {
|
|
118
135
|
const url = getStreamRecordsUrl(config, streamName, { seq_num, clamp: true })
|
|
119
|
-
return { url, headers: getSSEHeaders(config
|
|
136
|
+
return { url, headers: getSSEHeaders(config) }
|
|
120
137
|
} else {
|
|
121
138
|
// Non-live pulls also stream over SSE. We ask S2 to return immediately when
|
|
122
139
|
// the tail is reached by setting wait=0 which gives us an explicit
|
|
123
140
|
// end-of-stream without requesting an arbitrarily large page size.
|
|
124
141
|
const url = getStreamRecordsUrl(config, streamName, { seq_num, wait: 0, clamp: true })
|
|
125
|
-
return { url, headers: getSSEHeaders(config
|
|
142
|
+
return { url, headers: getSSEHeaders(config) }
|
|
126
143
|
}
|
|
127
144
|
}
|
|
128
145
|
|
|
@@ -155,7 +172,7 @@ export const buildPushRequests = ({
|
|
|
155
172
|
return chunks.map((chunk) => ({
|
|
156
173
|
url,
|
|
157
174
|
method: 'POST' as const,
|
|
158
|
-
headers: getPushHeaders(config
|
|
175
|
+
headers: getPushHeaders(config),
|
|
159
176
|
body: JSON.stringify({ records: chunk.records }),
|
|
160
177
|
}))
|
|
161
178
|
}
|