@livestore/sync-s2 0.4.0-dev.9 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/api-schema.d.ts.map +1 -1
- package/dist/api-schema.js +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 +1 -1
- package/dist/decode.d.ts.map +1 -1
- package/dist/decode.js +1 -1
- package/dist/decode.js.map +1 -1
- package/dist/http-client-generated.d.ts +21 -21
- 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.d.ts +41 -0
- package/dist/limits.d.ts.map +1 -0
- package/dist/limits.js +90 -0
- package/dist/limits.js.map +1 -0
- package/dist/limits.test.d.ts +2 -0
- package/dist/limits.test.d.ts.map +1 -0
- package/dist/limits.test.js +30 -0
- package/dist/limits.test.js.map +1 -0
- package/dist/make-s2-url.d.ts.map +1 -1
- package/dist/make-s2-url.js.map +1 -1
- package/dist/mod.d.ts +1 -0
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +1 -0
- package/dist/mod.js.map +1 -1
- package/dist/s2-proxy-helpers.d.ts +26 -22
- package/dist/s2-proxy-helpers.d.ts.map +1 -1
- package/dist/s2-proxy-helpers.js +35 -33
- 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 +49 -17
- 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 +2 -1
- package/src/decode.ts +4 -3
- package/src/http-client-generated.ts +74 -53
- package/src/limits.test.ts +44 -0
- package/src/limits.ts +135 -0
- package/src/make-s2-url.ts +1 -0
- package/src/mod.ts +1 -0
- package/src/s2-proxy-helpers.ts +57 -47
- package/src/sync-provider.ts +78 -31
package/dist/sync-provider.d.ts
CHANGED
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
* DO NOT couple these systems together or assume 1:1 correspondence.
|
|
29
29
|
*
|
|
30
30
|
* Errors
|
|
31
|
-
* - push →
|
|
31
|
+
* - push → UnknownError on non‑2xx; pull → UnknownError on non‑2xx; ping/connect map timeouts to offline.
|
|
32
32
|
* - The proxy should surface helpful status codes and error bodies.
|
|
33
33
|
*/
|
|
34
|
-
import {
|
|
34
|
+
import { SyncBackend, UnknownError } from '@livestore/common';
|
|
35
35
|
import { type Duration, Schedule } from '@livestore/utils/effect';
|
|
36
36
|
import type { SyncMetadata } from './types.ts';
|
|
37
37
|
export interface SyncS2Options {
|
|
@@ -50,9 +50,9 @@ export interface SyncS2Options {
|
|
|
50
50
|
};
|
|
51
51
|
retry?: {
|
|
52
52
|
/** Custom retry schedule for non-live pulls (default: 2 recurs, 100ms spaced) */
|
|
53
|
-
pull?: Schedule.Schedule<number,
|
|
53
|
+
pull?: Schedule.Schedule<number, UnknownError>;
|
|
54
54
|
/** Custom retry schedule for pushes (default: 2 recurs, 100ms spaced) */
|
|
55
|
-
push?: Schedule.Schedule<number,
|
|
55
|
+
push?: Schedule.Schedule<number, UnknownError>;
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
58
|
export declare const defaultRetry: Schedule.Schedule<number, unknown, never>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-provider.d.ts","sourceRoot":"","sources":["../src/sync-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"sync-provider.d.ts","sourceRoot":"","sources":["../src/sync-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAG7D,OAAO,EACL,KAAK,QAAQ,EAMb,QAAQ,EAKT,MAAM,yBAAyB,CAAA;AAMhC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,MAAM,WAAW,aAAa;IAC5B,QAAQ,EACJ,MAAM,GACN;QACE,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;IACL,IAAI,CAAC,EAAE;QACL,yCAAyC;QACzC,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,uDAAuD;QACvD,cAAc,CAAC,EAAE,QAAQ,CAAC,aAAa,CAAA;QACvC,kDAAkD;QAClD,eAAe,CAAC,EAAE,QAAQ,CAAC,aAAa,CAAA;KACzC,CAAA;IACD,KAAK,CAAC,EAAE;QACN,iFAAiF;QACjF,IAAI,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;QAC9C,yEAAyE;QACzE,IAAI,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;KAC/C,CAAA;CACF;AAED,eAAO,MAAM,YAAY,2CAA6D,CAAA;AActF,eAAO,MAAM,eAAe,GACzB,wCAAwC,aAAa,KAAG,WAAW,CAAC,sBAAsB,CAAC,YAAY,CA+NpG,CAAA"}
|
package/dist/sync-provider.js
CHANGED
|
@@ -28,37 +28,43 @@
|
|
|
28
28
|
* DO NOT couple these systems together or assume 1:1 correspondence.
|
|
29
29
|
*
|
|
30
30
|
* Errors
|
|
31
|
-
* - push →
|
|
31
|
+
* - push → UnknownError on non‑2xx; pull → UnknownError on non‑2xx; ping/connect map timeouts to offline.
|
|
32
32
|
* - The proxy should surface helpful status codes and error bodies.
|
|
33
33
|
*/
|
|
34
|
-
import {
|
|
34
|
+
import { SyncBackend, UnknownError } from '@livestore/common';
|
|
35
35
|
import { shouldNeverHappen } from '@livestore/utils';
|
|
36
36
|
import { Effect, HttpClient, HttpClientRequest, HttpClientResponse, Option, Schedule, Schema, Sse, Stream, SubscriptionRef, } from '@livestore/utils/effect';
|
|
37
37
|
import * as ApiSchema from "./api-schema.js";
|
|
38
38
|
import { decodeReadBatch } from "./decode.js";
|
|
39
39
|
import * as HttpClientGenerated from "./http-client-generated.js";
|
|
40
|
+
import { chunkEventsForS2, S2LimitExceededError } from "./limits.js";
|
|
40
41
|
export const defaultRetry = Schedule.compose(Schedule.recurs(2), Schedule.spaced(100));
|
|
42
|
+
const getBrowserOrigin = () => {
|
|
43
|
+
if (typeof globalThis !== 'object' || globalThis === null || !('location' in globalThis)) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
const { location } = globalThis;
|
|
47
|
+
return typeof location?.origin === 'string' ? location.origin : undefined;
|
|
48
|
+
};
|
|
41
49
|
export const makeSyncBackend = ({ endpoint, ping: pingOptions, retry }) => ({ storeId, payload }) => Effect.gen(function* () {
|
|
42
50
|
const isConnected = yield* SubscriptionRef.make(false);
|
|
43
51
|
const pullEndpoint = typeof endpoint === 'string' ? endpoint : endpoint.pull;
|
|
44
52
|
const pushEndpoint = typeof endpoint === 'string' ? endpoint : endpoint.push;
|
|
45
53
|
const pingEndpoint = typeof endpoint === 'string' ? endpoint : endpoint.ping;
|
|
46
54
|
const httpClient = yield* HttpClient.HttpClient;
|
|
47
|
-
const
|
|
48
|
-
|
|
55
|
+
const browserOrigin = getBrowserOrigin();
|
|
56
|
+
const pullEndpointHasSameOrigin = pullEndpoint.startsWith('/') || (browserOrigin !== undefined && browserOrigin === new URL(pullEndpoint).origin);
|
|
49
57
|
const pingTimeout = pingOptions?.requestTimeout ?? 10_000;
|
|
50
58
|
const ping = Effect.gen(function* () {
|
|
51
59
|
yield* httpClient.pipe(HttpClient.filterStatusOk).head(pingEndpoint);
|
|
52
60
|
yield* SubscriptionRef.set(isConnected, true);
|
|
53
|
-
}).pipe(
|
|
61
|
+
}).pipe(UnknownError.mapToUnknownError, Effect.timeout(pingTimeout), Effect.catchTag('TimeoutException', () => SubscriptionRef.set(isConnected, false)));
|
|
54
62
|
const pingInterval = pingOptions?.requestInterval ?? 10_000;
|
|
55
63
|
if (pingOptions?.enabled !== false) {
|
|
56
64
|
yield* ping.pipe(Effect.repeat(Schedule.spaced(pingInterval)), Effect.tapCauseLogPretty, Effect.forkScoped);
|
|
57
65
|
}
|
|
58
66
|
// No need to connect if the pull endpoint has the same origin as the current page
|
|
59
|
-
const connect = pullEndpointHasSameOrigin
|
|
60
|
-
? Effect.void
|
|
61
|
-
: ping.pipe(UnexpectedError.mapToUnexpectedError);
|
|
67
|
+
const connect = pullEndpointHasSameOrigin === true ? Effect.void : ping.pipe(UnknownError.mapToUnknownError);
|
|
62
68
|
const runPullSse = (cursor, live) => {
|
|
63
69
|
// Extract S2 seqNum from metadata for SSE cursor
|
|
64
70
|
const s2SeqNum = cursor.pipe(Option.flatMap((_) => _.metadata), Option.map((_) => _.s2SeqNum), Option.getOrElse(() => 'from-start'));
|
|
@@ -75,7 +81,7 @@ export const makeSyncBackend = ({ endpoint, ping: pingOptions, retry }) => ({ st
|
|
|
75
81
|
if (evt === 'ping')
|
|
76
82
|
return Option.none();
|
|
77
83
|
if (evt === 'error') {
|
|
78
|
-
return yield* new
|
|
84
|
+
return yield* new UnknownError({ cause: new Error(`SSE error: ${msg.data}`) });
|
|
79
85
|
}
|
|
80
86
|
if (evt === 'batch') {
|
|
81
87
|
const readBatch = yield* Schema.decode(Schema.parseJson(HttpClientGenerated.ReadBatch))(msg.data);
|
|
@@ -98,12 +104,12 @@ export const makeSyncBackend = ({ endpoint, ping: pingOptions, retry }) => ({ st
|
|
|
98
104
|
}
|
|
99
105
|
return shouldNeverHappen(`Unexpected SSE event: ${evt}`, msg);
|
|
100
106
|
})), Stream.filterMap((_) => _), // filter out Option.none()
|
|
101
|
-
Stream.mapError((cause) =>
|
|
107
|
+
Stream.mapError((cause) => cause._tag === 'UnknownError' ? cause : new UnknownError({ cause })), Stream.retry(retry?.pull ?? defaultRetry));
|
|
102
108
|
};
|
|
103
109
|
const ssePull = (startCursor) => {
|
|
104
110
|
const computeNextCursor = (lastItem, current) => lastItem.pipe(Option.flatMap((item) => {
|
|
105
111
|
const lastBatchItem = item.batch.at(-1);
|
|
106
|
-
if (
|
|
112
|
+
if (lastBatchItem == null)
|
|
107
113
|
return Option.none();
|
|
108
114
|
return Option.some({
|
|
109
115
|
eventSequenceNumber: lastBatchItem.eventEncoded.seqNum,
|
|
@@ -115,7 +121,7 @@ export const makeSyncBackend = ({ endpoint, ping: pingOptions, retry }) => ({ st
|
|
|
115
121
|
batch: [],
|
|
116
122
|
pageInfo: SyncBackend.pageInfoNoMore,
|
|
117
123
|
}));
|
|
118
|
-
const stream = isFirst ? sseStream(false) : sseStream(true);
|
|
124
|
+
const stream = isFirst === true ? sseStream(false) : sseStream(true);
|
|
119
125
|
return stream.pipe(
|
|
120
126
|
// Reconnect from last item if stream
|
|
121
127
|
Stream.concatWithLastElement((lastItem) => loop(computeNextCursor(lastItem, cursor), false)));
|
|
@@ -125,7 +131,7 @@ export const makeSyncBackend = ({ endpoint, ping: pingOptions, retry }) => ({ st
|
|
|
125
131
|
return SyncBackend.of({
|
|
126
132
|
connect,
|
|
127
133
|
pull: (cursor, options) => {
|
|
128
|
-
if (options?.live) {
|
|
134
|
+
if (options?.live === true) {
|
|
129
135
|
return ssePull(cursor);
|
|
130
136
|
}
|
|
131
137
|
else {
|
|
@@ -135,10 +141,36 @@ export const makeSyncBackend = ({ endpoint, ping: pingOptions, retry }) => ({ st
|
|
|
135
141
|
}));
|
|
136
142
|
}
|
|
137
143
|
},
|
|
138
|
-
push: (batch) =>
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
144
|
+
push: (batch) => Effect.gen(function* () {
|
|
145
|
+
const toUnknownError = (cause) => {
|
|
146
|
+
if (cause instanceof UnknownError) {
|
|
147
|
+
return cause;
|
|
148
|
+
}
|
|
149
|
+
if (cause instanceof S2LimitExceededError) {
|
|
150
|
+
const note = cause.limitType === 'record-metered-bytes'
|
|
151
|
+
? `S2 record exceeded ${cause.max} metered bytes (actual: ${cause.actual})`
|
|
152
|
+
: `S2 batch exceeded ${cause.max} (type: ${cause.limitType}, actual: ${cause.actual})`;
|
|
153
|
+
return new UnknownError({
|
|
154
|
+
cause,
|
|
155
|
+
note,
|
|
156
|
+
payload: {
|
|
157
|
+
limitType: cause.limitType,
|
|
158
|
+
max: cause.max,
|
|
159
|
+
actual: cause.actual,
|
|
160
|
+
recordIndex: cause.recordIndex,
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
return new UnknownError({ cause });
|
|
165
|
+
};
|
|
166
|
+
const chunks = yield* Effect.sync(() => chunkEventsForS2(batch)).pipe(Effect.mapError(toUnknownError));
|
|
167
|
+
for (const chunk of chunks) {
|
|
168
|
+
yield* HttpClientRequest.schemaBodyJson(ApiSchema.PushPayload)(HttpClientRequest.post(pushEndpoint), {
|
|
169
|
+
storeId,
|
|
170
|
+
batch: chunk.events,
|
|
171
|
+
}).pipe(Effect.andThen(httpClient.pipe(HttpClient.filterStatusOk).execute), Effect.andThen(HttpClientResponse.schemaBodyJson(ApiSchema.PushResponse)), Effect.mapError(toUnknownError), Effect.retry(retry?.push ?? defaultRetry));
|
|
172
|
+
}
|
|
173
|
+
}),
|
|
142
174
|
ping,
|
|
143
175
|
isConnected,
|
|
144
176
|
metadata: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-provider.js","sourceRoot":"","sources":["../src/sync-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"sync-provider.js","sourceRoot":"","sources":["../src/sync-provider.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,27 +1,90 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livestore/sync-s2",
|
|
3
|
-
"version": "0.4.0
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/livestorejs/livestore.git"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"package.json",
|
|
12
|
+
"src"
|
|
13
|
+
],
|
|
4
14
|
"type": "module",
|
|
5
15
|
"sideEffects": false,
|
|
6
16
|
"exports": {
|
|
7
17
|
".": "./dist/mod.js",
|
|
8
18
|
"./s2-proxy-helpers": "./dist/s2-proxy-helpers.js"
|
|
9
19
|
},
|
|
10
|
-
"dependencies": {
|
|
11
|
-
"@livestore/common": "0.4.0-dev.9",
|
|
12
|
-
"@livestore/livestore": "0.4.0-dev.9",
|
|
13
|
-
"@livestore/utils": "0.4.0-dev.9"
|
|
14
|
-
},
|
|
15
|
-
"devDependencies": {},
|
|
16
|
-
"files": [
|
|
17
|
-
"package.json",
|
|
18
|
-
"src",
|
|
19
|
-
"dist"
|
|
20
|
-
],
|
|
21
|
-
"license": "Apache-2.0",
|
|
22
20
|
"publishConfig": {
|
|
23
21
|
"access": "public"
|
|
24
22
|
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@livestore/common": "^0.4.0",
|
|
25
|
+
"@livestore/livestore": "^0.4.0",
|
|
26
|
+
"@livestore/utils": "^0.4.0"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@effect/ai": "0.35.0",
|
|
30
|
+
"@effect/cli": "0.75.1",
|
|
31
|
+
"@effect/cluster": "0.58.2",
|
|
32
|
+
"@effect/experimental": "0.60.0",
|
|
33
|
+
"@effect/opentelemetry": "0.63.0",
|
|
34
|
+
"@effect/platform": "0.96.1",
|
|
35
|
+
"@effect/platform-browser": "0.76.0",
|
|
36
|
+
"@effect/platform-bun": "0.89.0",
|
|
37
|
+
"@effect/platform-node": "0.106.0",
|
|
38
|
+
"@effect/printer": "0.49.0",
|
|
39
|
+
"@effect/printer-ansi": "0.49.0",
|
|
40
|
+
"@effect/rpc": "0.75.1",
|
|
41
|
+
"@effect/sql": "0.51.1",
|
|
42
|
+
"@effect/typeclass": "0.40.0",
|
|
43
|
+
"@effect/vitest": "0.29.0",
|
|
44
|
+
"@opentelemetry/api": "1.9.0",
|
|
45
|
+
"@opentelemetry/resources": "2.2.0",
|
|
46
|
+
"@standard-schema/spec": "1.1.0",
|
|
47
|
+
"effect": "3.21.2",
|
|
48
|
+
"vitest": "3.2.4"
|
|
49
|
+
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"@effect/ai": "^0.35.0",
|
|
52
|
+
"@effect/cli": "^0.75.1",
|
|
53
|
+
"@effect/cluster": "^0.58.2",
|
|
54
|
+
"@effect/experimental": "^0.60.0",
|
|
55
|
+
"@effect/opentelemetry": "^0.63.0",
|
|
56
|
+
"@effect/platform": "^0.96.1",
|
|
57
|
+
"@effect/platform-browser": "^0.76.0",
|
|
58
|
+
"@effect/platform-bun": "^0.89.0",
|
|
59
|
+
"@effect/platform-node": "^0.106.0",
|
|
60
|
+
"@effect/printer": "^0.49.0",
|
|
61
|
+
"@effect/printer-ansi": "^0.49.0",
|
|
62
|
+
"@effect/rpc": "^0.75.1",
|
|
63
|
+
"@effect/sql": "^0.51.1",
|
|
64
|
+
"@effect/typeclass": "^0.40.0",
|
|
65
|
+
"@effect/vitest": "^0.29.0",
|
|
66
|
+
"@opentelemetry/api": "^1.9.0",
|
|
67
|
+
"@opentelemetry/resources": "^2.2.0",
|
|
68
|
+
"@standard-schema/spec": "^1.1.0",
|
|
69
|
+
"effect": "^3.21.2"
|
|
70
|
+
},
|
|
71
|
+
"$genie": {
|
|
72
|
+
"source": "package.json.genie.ts",
|
|
73
|
+
"warning": "DO NOT EDIT - changes will be overwritten",
|
|
74
|
+
"workspaceClosureDirs": [
|
|
75
|
+
"packages/@livestore/adapter-web",
|
|
76
|
+
"packages/@livestore/common",
|
|
77
|
+
"packages/@livestore/common-cf",
|
|
78
|
+
"packages/@livestore/devtools-web-common",
|
|
79
|
+
"packages/@livestore/livestore",
|
|
80
|
+
"packages/@livestore/sqlite-wasm",
|
|
81
|
+
"packages/@livestore/sync-s2",
|
|
82
|
+
"packages/@livestore/utils",
|
|
83
|
+
"packages/@livestore/utils-dev",
|
|
84
|
+
"packages/@livestore/wa-sqlite",
|
|
85
|
+
"packages/@livestore/webmesh"
|
|
86
|
+
]
|
|
87
|
+
},
|
|
25
88
|
"scripts": {
|
|
26
89
|
"build": "",
|
|
27
90
|
"test": "echo 'No tests yet'"
|
package/src/api-schema.test.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { Schema } from '@livestore/utils/effect'
|
|
2
1
|
import { describe, expect, it } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { Schema } from '@livestore/utils/effect'
|
|
4
|
+
|
|
3
5
|
import * as Api from './api-schema.ts'
|
|
4
6
|
import { decodePullArgsFromSearchParams } from './make-s2-url.ts'
|
|
5
7
|
import { s2SeqNum } from './types.ts'
|
package/src/api-schema.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LiveStoreEvent } from '@livestore/common/schema'
|
|
2
2
|
import { Schema } from '@livestore/utils/effect'
|
|
3
|
+
|
|
3
4
|
import { S2SeqNum } from './types.ts'
|
|
4
5
|
|
|
5
6
|
export const PullArgs = Schema.Struct({
|
|
@@ -11,7 +12,7 @@ export const PullArgs = Schema.Struct({
|
|
|
11
12
|
|
|
12
13
|
export const PushPayload = Schema.Struct({
|
|
13
14
|
storeId: Schema.String,
|
|
14
|
-
batch: Schema.Array(LiveStoreEvent.
|
|
15
|
+
batch: Schema.Array(LiveStoreEvent.Global.Encoded),
|
|
15
16
|
})
|
|
16
17
|
|
|
17
18
|
export type PullArgs = typeof PullArgs.Type
|
package/src/decode.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { LiveStoreEvent } from '@livestore/common/schema'
|
|
2
2
|
import { Option, Schema } from '@livestore/utils/effect'
|
|
3
|
+
|
|
3
4
|
import type * as HttpClientGenerated from './http-client-generated.ts'
|
|
4
5
|
import { S2SeqNum } from './types.ts'
|
|
5
6
|
|
|
6
7
|
const ReadBatchSchema = Schema.Struct({
|
|
7
8
|
records: Schema.Array(
|
|
8
9
|
Schema.Struct({
|
|
9
|
-
body: Schema.optional(Schema.parseJson(LiveStoreEvent.
|
|
10
|
+
body: Schema.optional(Schema.parseJson(LiveStoreEvent.Global.Encoded)),
|
|
10
11
|
seq_num: S2SeqNum,
|
|
11
12
|
}),
|
|
12
13
|
),
|
|
@@ -15,12 +16,12 @@ const ReadBatchSchema = Schema.Struct({
|
|
|
15
16
|
export const decodeReadBatch = (
|
|
16
17
|
readBatch: typeof HttpClientGenerated.ReadBatch.Type,
|
|
17
18
|
): ReadonlyArray<{
|
|
18
|
-
eventEncoded: LiveStoreEvent.
|
|
19
|
+
eventEncoded: LiveStoreEvent.Global.Encoded
|
|
19
20
|
metadata: Option.Option<{ s2SeqNum: S2SeqNum }>
|
|
20
21
|
}> => {
|
|
21
22
|
const decoded = Schema.decodeSync(ReadBatchSchema)(readBatch)
|
|
22
23
|
return decoded.records
|
|
23
|
-
.filter((r): r is { body: LiveStoreEvent.
|
|
24
|
+
.filter((r): r is { body: LiveStoreEvent.Global.Encoded; seq_num: S2SeqNum } => r.body !== undefined)
|
|
24
25
|
.map((r) => ({
|
|
25
26
|
eventEncoded: r.body,
|
|
26
27
|
metadata: Option.some({ s2SeqNum: r.seq_num }),
|