@livestore/sync-s2 0.0.0-snapshot-39b490a4d9054515b0012244297c45505059cf72 → 0.0.0-snapshot-4b42ef6ef0c52dda5b8633a10addf45134e4cafe
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/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/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 +14 -19
- package/dist/s2-proxy-helpers.d.ts.map +1 -1
- package/dist/s2-proxy-helpers.js +12 -18
- package/dist/s2-proxy-helpers.js.map +1 -1
- package/dist/sync-provider.d.ts.map +1 -1
- package/dist/sync-provider.js +36 -4
- package/dist/sync-provider.js.map +1 -1
- package/package.json +4 -4
- package/src/limits.test.ts +42 -0
- package/src/limits.ts +135 -0
- package/src/mod.ts +1 -0
- package/src/s2-proxy-helpers.ts +22 -30
- package/src/sync-provider.ts +48 -9
package/dist/limits.d.ts
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
import type { LiveStoreEvent } from '@livestore/common/schema';
|
2
|
+
import { Schema } from '@livestore/utils/effect';
|
3
|
+
/**
|
4
|
+
* Maximum metered size of a single record (docs: https://s2.dev/docs/limits#records).
|
5
|
+
*/
|
6
|
+
export declare const MAX_RECORD_METERED_BYTES = 1048576;
|
7
|
+
/**
|
8
|
+
* Maximum combined metered size of a batch append (docs: https://s2.dev/docs/limits#records).
|
9
|
+
*/
|
10
|
+
export declare const MAX_BATCH_METERED_BYTES = 1048576;
|
11
|
+
/**
|
12
|
+
* Maximum number of records per append (docs: https://s2.dev/docs/limits#records).
|
13
|
+
*/
|
14
|
+
export declare const MAX_RECORDS_PER_BATCH = 1000;
|
15
|
+
declare const S2LimitExceededError_base: Schema.TaggedErrorClass<S2LimitExceededError, "S2LimitExceededError", {
|
16
|
+
readonly _tag: Schema.tag<"S2LimitExceededError">;
|
17
|
+
} & {
|
18
|
+
limitType: Schema.Literal<["record-metered-bytes", "batch-metered-bytes", "batch-count"]>;
|
19
|
+
max: typeof Schema.Number;
|
20
|
+
actual: typeof Schema.Number;
|
21
|
+
recordIndex: Schema.optional<typeof Schema.Number>;
|
22
|
+
}>;
|
23
|
+
export declare class S2LimitExceededError extends S2LimitExceededError_base {
|
24
|
+
}
|
25
|
+
export interface AppendRecordBody {
|
26
|
+
readonly body?: string;
|
27
|
+
readonly headers?: ReadonlyArray<{
|
28
|
+
readonly name: string;
|
29
|
+
readonly value: string;
|
30
|
+
}>;
|
31
|
+
}
|
32
|
+
export declare const computeRecordMeteredBytes: (record: AppendRecordBody) => number;
|
33
|
+
export declare const computeBatchMeteredBytes: (records: ReadonlyArray<AppendRecordBody>) => number;
|
34
|
+
export interface S2Chunk {
|
35
|
+
readonly events: ReadonlyArray<LiveStoreEvent.AnyEncodedGlobal>;
|
36
|
+
readonly records: ReadonlyArray<AppendRecordBody>;
|
37
|
+
readonly meteredBytes: number;
|
38
|
+
}
|
39
|
+
export declare const chunkEventsForS2: (events: ReadonlyArray<LiveStoreEvent.AnyEncodedGlobal>) => ReadonlyArray<S2Chunk>;
|
40
|
+
export {};
|
41
|
+
//# sourceMappingURL=limits.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../src/limits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAiB,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAI/D;;GAEG;AACH,eAAO,MAAM,wBAAwB,UAAY,CAAA;AAEjD;;GAEG;AACH,eAAO,MAAM,uBAAuB,UAAY,CAAA;AAEhD;;GAEG;AACH,eAAO,MAAM,qBAAqB,OAAQ,CAAA;;;;;;;;;AAI1C,qBAAa,oBAAqB,SAAQ,yBAKxC;CAAG;AAEL,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACpF;AAMD,eAAO,MAAM,yBAAyB,GAAI,QAAQ,gBAAgB,KAAG,MASpE,CAAA;AAED,eAAO,MAAM,wBAAwB,GAAI,SAAS,aAAa,CAAC,gBAAgB,CAAC,KAAG,MACP,CAAA;AAS7E,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAA;IAC/D,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAA;IACjD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAC9B;AAuCD,eAAO,MAAM,gBAAgB,GAAI,QAAQ,aAAa,CAAC,cAAc,CAAC,gBAAgB,CAAC,KAAG,aAAa,CAAC,OAAO,CA+B9G,CAAA"}
|
package/dist/limits.js
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
import { splitChunkBySize } from '@livestore/common/sync';
|
2
|
+
import { Chunk, Effect, Schema } from '@livestore/utils/effect';
|
3
|
+
const textEncoder = new TextEncoder();
|
4
|
+
/**
|
5
|
+
* Maximum metered size of a single record (docs: https://s2.dev/docs/limits#records).
|
6
|
+
*/
|
7
|
+
export const MAX_RECORD_METERED_BYTES = 1_048_576; // 1 MiB
|
8
|
+
/**
|
9
|
+
* Maximum combined metered size of a batch append (docs: https://s2.dev/docs/limits#records).
|
10
|
+
*/
|
11
|
+
export const MAX_BATCH_METERED_BYTES = 1_048_576; // 1 MiB
|
12
|
+
/**
|
13
|
+
* Maximum number of records per append (docs: https://s2.dev/docs/limits#records).
|
14
|
+
*/
|
15
|
+
export const MAX_RECORDS_PER_BATCH = 1_000;
|
16
|
+
const LimitType = Schema.Literal('record-metered-bytes', 'batch-metered-bytes', 'batch-count');
|
17
|
+
export class S2LimitExceededError extends Schema.TaggedError()('S2LimitExceededError', {
|
18
|
+
limitType: LimitType,
|
19
|
+
max: Schema.Number,
|
20
|
+
actual: Schema.Number,
|
21
|
+
recordIndex: Schema.optional(Schema.Number),
|
22
|
+
}) {
|
23
|
+
}
|
24
|
+
// S2 measures bodies/headers in UTF‑8 bytes; centralising this helper keeps the
|
25
|
+
// formula readable and consistent with the docs.
|
26
|
+
const utf8ByteLength = (value) => textEncoder.encode(value).byteLength;
|
27
|
+
export const computeRecordMeteredBytes = (record) => {
|
28
|
+
const headers = record.headers ?? [];
|
29
|
+
const headerCount = headers.length;
|
30
|
+
const headerBytes = headers.reduce((acc, header) => acc + utf8ByteLength(header.name) + utf8ByteLength(header.value), 0);
|
31
|
+
const bodyBytes = record.body === undefined ? 0 : utf8ByteLength(record.body);
|
32
|
+
return 8 + 2 * headerCount + headerBytes + bodyBytes;
|
33
|
+
};
|
34
|
+
export const computeBatchMeteredBytes = (records) => records.reduce((acc, record) => acc + computeRecordMeteredBytes(record), 0);
|
35
|
+
// Pre-stringify events and pre-compute per-record metered bytes so we only pay
|
36
|
+
// the JSON cost once when chunking large batches.
|
37
|
+
const convertEventsToPrepared = (events) => events.map((event, index) => {
|
38
|
+
const body = JSON.stringify(event);
|
39
|
+
const record = { body };
|
40
|
+
const meteredBytes = computeRecordMeteredBytes(record);
|
41
|
+
if (meteredBytes > MAX_RECORD_METERED_BYTES) {
|
42
|
+
throw new S2LimitExceededError({
|
43
|
+
limitType: 'record-metered-bytes',
|
44
|
+
max: MAX_RECORD_METERED_BYTES,
|
45
|
+
actual: meteredBytes,
|
46
|
+
recordIndex: index,
|
47
|
+
});
|
48
|
+
}
|
49
|
+
return { event, record, meteredBytes, index };
|
50
|
+
});
|
51
|
+
// Summarises a chunk’s metered bytes. Passed to splitChunkBySize so we enforce
|
52
|
+
// S2 limits directly instead of relying on JSON size heuristics.
|
53
|
+
const makeChunkMeasure = (items) => items.reduce((acc, item) => acc + item.meteredBytes, 0);
|
54
|
+
const mapPreparedChunks = (chunks) => Chunk.toReadonlyArray(chunks).map((chunk) => {
|
55
|
+
const chunkItems = Chunk.toReadonlyArray(chunk);
|
56
|
+
const events = chunkItems.map((item) => item.event);
|
57
|
+
const records = chunkItems.map((item) => item.record);
|
58
|
+
return {
|
59
|
+
events,
|
60
|
+
records,
|
61
|
+
meteredBytes: makeChunkMeasure(chunkItems),
|
62
|
+
};
|
63
|
+
});
|
64
|
+
export const chunkEventsForS2 = (events) => {
|
65
|
+
if (events.length === 0) {
|
66
|
+
return [];
|
67
|
+
}
|
68
|
+
const prepared = convertEventsToPrepared(events);
|
69
|
+
try {
|
70
|
+
const chunks = Chunk.fromIterable(prepared).pipe(splitChunkBySize({
|
71
|
+
maxItems: MAX_RECORDS_PER_BATCH,
|
72
|
+
maxBytes: MAX_BATCH_METERED_BYTES,
|
73
|
+
encode: (items) => ({ records: items.map((item) => item.record) }),
|
74
|
+
measure: makeChunkMeasure,
|
75
|
+
}), Effect.runSync);
|
76
|
+
return mapPreparedChunks(chunks);
|
77
|
+
}
|
78
|
+
catch (error) {
|
79
|
+
if (error && typeof error === 'object' && error._tag === 'OversizeChunkItemError') {
|
80
|
+
const oversize = error;
|
81
|
+
throw new S2LimitExceededError({
|
82
|
+
limitType: 'record-metered-bytes',
|
83
|
+
max: oversize.maxBytes,
|
84
|
+
actual: oversize.size,
|
85
|
+
});
|
86
|
+
}
|
87
|
+
throw error;
|
88
|
+
}
|
89
|
+
};
|
90
|
+
//# sourceMappingURL=limits.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"limits.js","sourceRoot":"","sources":["../src/limits.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"limits.test.d.ts","sourceRoot":"","sources":["../src/limits.test.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
2
|
+
import { chunkEventsForS2, computeRecordMeteredBytes, MAX_BATCH_METERED_BYTES, MAX_RECORD_METERED_BYTES, S2LimitExceededError, } from "./limits.js";
|
3
|
+
const encoder = new TextEncoder();
|
4
|
+
const makeEvent = (payloadLength, index = 0) => ({
|
5
|
+
name: `event-${index}`,
|
6
|
+
args: { payload: 'x'.repeat(payloadLength) },
|
7
|
+
seqNum: index,
|
8
|
+
parentSeqNum: index,
|
9
|
+
clientId: 'client',
|
10
|
+
sessionId: 'session',
|
11
|
+
});
|
12
|
+
describe('S2 limits helpers', () => {
|
13
|
+
it('computes metered bytes for record bodies', () => {
|
14
|
+
const record = { body: JSON.stringify({ hello: 'world' }) };
|
15
|
+
const expected = 8 + encoder.encode(record.body ?? '').byteLength;
|
16
|
+
expect(computeRecordMeteredBytes(record)).toBe(expected);
|
17
|
+
});
|
18
|
+
it('splits large batches while respecting metered byte limits', () => {
|
19
|
+
const events = [makeEvent(400_000, 1), makeEvent(400_000, 2), makeEvent(400_000, 3)];
|
20
|
+
const chunks = chunkEventsForS2(events);
|
21
|
+
expect(chunks).toHaveLength(2);
|
22
|
+
expect(chunks.map((chunk) => chunk.events.length)).toStrictEqual([2, 1]);
|
23
|
+
expect(chunks.every((chunk) => chunk.meteredBytes <= MAX_BATCH_METERED_BYTES)).toBe(true);
|
24
|
+
});
|
25
|
+
it('throws when a single record exceeds the metered byte cap', () => {
|
26
|
+
const oversize = makeEvent(MAX_RECORD_METERED_BYTES, 1);
|
27
|
+
expect(() => chunkEventsForS2([oversize])).toThrow(S2LimitExceededError);
|
28
|
+
});
|
29
|
+
});
|
30
|
+
//# sourceMappingURL=limits.test.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"limits.test.js","sourceRoot":"","sources":["../src/limits.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EACL,gBAAgB,EAChB,yBAAyB,EACzB,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,aAAa,CAAA;AAEpB,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;AAEjC,MAAM,SAAS,GAAG,CAAC,aAAqB,EAAE,KAAK,GAAG,CAAC,EAAmC,EAAE,CAAC,CAAC;IACxF,IAAI,EAAE,SAAS,KAAK,EAAE;IACtB,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE;IAC5C,MAAM,EAAE,KAAsD;IAC9D,YAAY,EAAE,KAAsD;IACpE,QAAQ,EAAE,QAAQ;IAClB,SAAS,EAAE,SAAS;CACrB,CAAC,CAAA;AAEF,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,CAAA;QAC3D,MAAM,QAAQ,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,UAAU,CAAA;QACjE,MAAM,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAC1D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,MAAM,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAA;QACpF,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAA;QAEvC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;QAC9B,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACxE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,IAAI,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC3F,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,QAAQ,GAAG,SAAS,CAAC,wBAAwB,EAAE,CAAC,CAAC,CAAA;QACvD,MAAM,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAA;IAC1E,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
package/dist/mod.d.ts
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
export * as ApiSchema from './api-schema.ts';
|
2
2
|
export * as HttpClientGenerated from './http-client-generated.ts';
|
3
|
+
export * from './limits.ts';
|
3
4
|
export * from './make-s2-url.ts';
|
4
5
|
export * from './s2-proxy-helpers.ts';
|
5
6
|
export { makeSyncBackend, type SyncS2Options } from './sync-provider.ts';
|
package/dist/mod.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAA;AAC5C,OAAO,KAAK,mBAAmB,MAAM,4BAA4B,CAAA;AACjE,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,OAAO,EAAE,eAAe,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACxE,YAAY,EAAE,QAAQ,IAAI,YAAY,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC5F,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA"}
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAA;AAC5C,OAAO,KAAK,mBAAmB,MAAM,4BAA4B,CAAA;AACjE,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,OAAO,EAAE,eAAe,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACxE,YAAY,EAAE,QAAQ,IAAI,YAAY,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC5F,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/mod.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
export * as ApiSchema from "./api-schema.js";
|
2
2
|
export * as HttpClientGenerated from "./http-client-generated.js";
|
3
|
+
export * from "./limits.js";
|
3
4
|
export * from "./make-s2-url.js";
|
4
5
|
export * from "./s2-proxy-helpers.js";
|
5
6
|
export { makeSyncBackend } from "./sync-provider.js";
|
package/dist/mod.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAA;AAC5C,OAAO,KAAK,mBAAmB,MAAM,4BAA4B,CAAA;AACjE,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,OAAO,EAAE,eAAe,EAAsB,MAAM,oBAAoB,CAAA;AAExE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA"}
|
1
|
+
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAA;AAC5C,OAAO,KAAK,mBAAmB,MAAM,4BAA4B,CAAA;AACjE,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,OAAO,EAAE,eAAe,EAAsB,MAAM,oBAAoB,CAAA;AAExE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA"}
|
@@ -33,30 +33,25 @@ export declare const buildPullRequest: ({ config, args, }: {
|
|
33
33
|
url: string;
|
34
34
|
headers: Record<string, string>;
|
35
35
|
};
|
36
|
-
export
|
36
|
+
export interface S2PushRequest {
|
37
|
+
readonly url: string;
|
38
|
+
readonly method: 'POST';
|
39
|
+
readonly headers: Record<string, string>;
|
40
|
+
readonly body: string;
|
41
|
+
}
|
42
|
+
/**
|
43
|
+
* Builds one or more append requests against S2. The helper applies the
|
44
|
+
* documented 1 MiB / 1000-record limits via `chunkEventsForS2`, so callers
|
45
|
+
* receive a request per compliant chunk instead of hitting 413 responses at
|
46
|
+
* runtime.
|
47
|
+
*/
|
48
|
+
export declare const buildPushRequests: ({ config, storeId, batch, }: {
|
37
49
|
config: S2Config;
|
38
50
|
storeId: string;
|
39
51
|
batch: readonly LiveStoreEvent.AnyEncodedGlobal[];
|
40
|
-
}) =>
|
41
|
-
url: string;
|
42
|
-
method: "POST";
|
43
|
-
headers: Record<string, string>;
|
44
|
-
/** JSON-encoded batch */
|
45
|
-
body: string;
|
46
|
-
};
|
52
|
+
}) => ReadonlyArray<S2PushRequest>;
|
47
53
|
export declare const emptyBatchResponse: () => Response;
|
48
54
|
export declare const sseKeepAliveResponse: () => Response;
|
49
55
|
export declare const successResponse: () => Response;
|
50
56
|
export declare const errorResponse: (message: string, status?: number) => Response;
|
51
|
-
export declare const formatBatchForS2: (batch: readonly LiveStoreEvent.AnyEncodedGlobal[]) => {
|
52
|
-
records: {
|
53
|
-
body: string;
|
54
|
-
}[];
|
55
|
-
};
|
56
|
-
export declare const asCurl: (request: {
|
57
|
-
url: string;
|
58
|
-
method: string;
|
59
|
-
headers: Record<string, string>;
|
60
|
-
body?: string;
|
61
|
-
}) => string;
|
62
57
|
//# sourceMappingURL=s2-proxy-helpers.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"s2-proxy-helpers.d.ts","sourceRoot":"","sources":["../src/s2-proxy-helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;
|
1
|
+
{"version":3,"file":"s2-proxy-helpers.d.ts","sourceRoot":"","sources":["../src/s2-proxy-helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAI/C,uCAAuC;AACvC,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAGD,eAAO,MAAM,WAAW,GAAI,QAAQ,QAAQ,EAAE,MAAM,MAAM,KAAG,MAG5D,CAAA;AAED,eAAO,MAAM,aAAa,GAAI,QAAQ,QAAQ,EAAE,MAAM,MAAM,KAAG,MAG9D,CAAA;AAED,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,QAAQ,EAChB,QAAQ,MAAM,EACd,SAAS;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KAC5E,MAeF,CAAA;AAGD,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAElE,CAAA;AAEF,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAIjE,CAAA;AAEF,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAIlE,CAAA;AAGF,eAAO,MAAM,WAAW,GAAU,QAAQ,QAAQ,KAAG,OAAO,CAAC,IAAI,CAahE,CAAA;AAED,eAAO,MAAM,YAAY,GAAU,QAAQ,QAAQ,EAAE,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAajF,CAAA;AAGD,eAAO,MAAM,gBAAgB,GAAI,mBAG9B;IACD,MAAM,EAAE,QAAQ,CAAA;IAChB,IAAI,EAAE,QAAQ,CAAA;CACf,KAAG;IACF,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAiBhC,CAAA;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,6BAI/B;IACD,MAAM,EAAE,QAAQ,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,SAAS,cAAc,CAAC,gBAAgB,EAAE,CAAA;CAClD,KAAG,aAAa,CAAC,aAAa,CAW9B,CAAA;AAGD,eAAO,MAAM,kBAAkB,QAAO,QAIrC,CAAA;AAED,eAAO,MAAM,oBAAoB,QAAO,QAKvC,CAAA;AAED,eAAO,MAAM,eAAe,QAAO,QAKlC,CAAA;AAED,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,EAAE,eAAY,KAAG,QAK7D,CAAA"}
|
package/dist/s2-proxy-helpers.js
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
* Helper functions for implementing S2 API proxies.
|
3
3
|
* These utilities reduce duplication when building HTTP endpoints that bridge to S2.
|
4
4
|
*/
|
5
|
+
import { chunkEventsForS2 } from "./limits.js";
|
5
6
|
import { makeS2StreamName } from "./make-s2-url.js";
|
6
7
|
// URL construction helpers
|
7
8
|
export const getBasinUrl = (config, path) => {
|
@@ -94,15 +95,22 @@ export const buildPullRequest = ({ config, args, }) => {
|
|
94
95
|
return { url, headers: getSSEHeaders(config.token) };
|
95
96
|
}
|
96
97
|
};
|
97
|
-
|
98
|
+
/**
|
99
|
+
* Builds one or more append requests against S2. The helper applies the
|
100
|
+
* documented 1 MiB / 1000-record limits via `chunkEventsForS2`, so callers
|
101
|
+
* receive a request per compliant chunk instead of hitting 413 responses at
|
102
|
+
* runtime.
|
103
|
+
*/
|
104
|
+
export const buildPushRequests = ({ config, storeId, batch, }) => {
|
98
105
|
const streamName = makeS2StreamName(storeId);
|
99
106
|
const url = getBasinUrl(config, `/streams/${encodeURIComponent(streamName)}/records`);
|
100
|
-
|
107
|
+
const chunks = chunkEventsForS2(batch);
|
108
|
+
return chunks.map((chunk) => ({
|
101
109
|
url,
|
102
110
|
method: 'POST',
|
103
111
|
headers: getPushHeaders(config.token),
|
104
|
-
body: JSON.stringify(
|
105
|
-
};
|
112
|
+
body: JSON.stringify({ records: chunk.records }),
|
113
|
+
}));
|
106
114
|
};
|
107
115
|
// Response helpers
|
108
116
|
export const emptyBatchResponse = () => {
|
@@ -128,18 +136,4 @@ export const errorResponse = (message, status = 500) => {
|
|
128
136
|
headers: { 'content-type': 'application/json' },
|
129
137
|
});
|
130
138
|
};
|
131
|
-
// Batch formatting helper
|
132
|
-
export const formatBatchForS2 = (batch) => {
|
133
|
-
return {
|
134
|
-
records: batch.map((ev) => ({ body: JSON.stringify(ev) })),
|
135
|
-
};
|
136
|
-
};
|
137
|
-
export const asCurl = (request) => {
|
138
|
-
const url = request.url;
|
139
|
-
const method = request.method;
|
140
|
-
const headers = Object.entries(request.headers).map(([key, value]) => `-H "${key}: ${value}"`);
|
141
|
-
const body = request.body;
|
142
|
-
const headersStr = headers.join(' ');
|
143
|
-
return `curl -X ${method} ${url} ${headersStr} ${body ? `-d '${body}'` : ''}`;
|
144
|
-
};
|
145
139
|
//# sourceMappingURL=s2-proxy-helpers.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"s2-proxy-helpers.js","sourceRoot":"","sources":["../src/s2-proxy-helpers.ts"],"names":[],"mappings":"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
|
1
|
+
{"version":3,"file":"s2-proxy-helpers.js","sourceRoot":"","sources":["../src/s2-proxy-helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAYnD,2BAA2B;AAC3B,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAgB,EAAE,IAAY,EAAU,EAAE;IACpE,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,IAAI,WAAW,MAAM,CAAC,KAAK,kBAAkB,CAAA;IAC1E,OAAO,GAAG,IAAI,GAAG,IAAI,EAAE,CAAA;AACzB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAgB,EAAE,IAAY,EAAU,EAAE;IACtE,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,IAAI,uBAAuB,CAAA;IAC1D,OAAO,GAAG,IAAI,GAAG,IAAI,EAAE,CAAA;AACzB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,MAAgB,EAChB,MAAc,EACd,MAA6E,EACrE,EAAE;IACV,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,YAAY,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IAClF,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAExB,MAAM,YAAY,GAAG,IAAI,eAAe,EAAE,CAAA;IAC1C,wFAAwF;IACxF,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;QAAE,YAAY,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAA;IAC3F,sFAAsF;IACtF,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;QAAE,YAAY,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;IACrF,uGAAuG;IACvG,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;QAAE,YAAY,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;IACrF,kGAAkG;IAClG,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;QAAE,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;IAElF,OAAO,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;AACnE,CAAC,CAAA;AAED,iBAAiB;AACjB,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAa,EAA0B,EAAE,CAAC,CAAC;IACxE,aAAa,EAAE,UAAU,KAAK,EAAE;CACjC,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAa,EAA0B,EAAE,CAAC,CAAC;IACvE,GAAG,cAAc,CAAC,KAAK,CAAC;IACxB,MAAM,EAAE,mBAAmB;IAC3B,WAAW,EAAE,KAAK;CACnB,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAa,EAA0B,EAAE,CAAC,CAAC;IACxE,GAAG,cAAc,CAAC,KAAK,CAAC;IACxB,cAAc,EAAE,kBAAkB;IAClC,WAAW,EAAE,KAAK;CACnB,CAAC,CAAA;AAEF,uBAAuB;AACvB,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,MAAgB,EAAiB,EAAE;IACnE,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE;YAC5C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,GAAG,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC;gBAC/B,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;SAC9C,CAAC,CAAA;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,4CAA4C;IAC9C,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,MAAgB,EAAE,MAAc,EAAiB,EAAE;IACpF,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE;YAC3C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,GAAG,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC;gBAC/B,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;SACjC,CAAC,CAAA;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,6CAA6C;IAC/C,CAAC;AACH,CAAC,CAAA;AAED,+BAA+B;AAC/B,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAC/B,MAAM,EACN,IAAI,GAIL,EAGC,EAAE;IACF,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACjD,wEAAwE;IACxE,8EAA8E;IAC9E,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAA;IAEtE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,mBAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QAC7E,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;IACtD,CAAC;SAAM,CAAC;QACN,4EAA4E;QAC5E,mEAAmE;QACnE,mEAAmE;QACnE,MAAM,GAAG,GAAG,mBAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QACtF,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;IACtD,CAAC;AACH,CAAC,CAAA;AASD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,EAChC,MAAM,EACN,OAAO,EACP,KAAK,GAKN,EAAgC,EAAE;IACjC,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAC5C,MAAM,GAAG,GAAG,WAAW,CAAC,MAAM,EAAE,YAAY,kBAAkB,CAAC,UAAU,CAAC,UAAU,CAAC,CAAA;IACrF,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAA;IAEtC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC5B,GAAG;QACH,MAAM,EAAE,MAAe;QACvB,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC;QACrC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;KACjD,CAAC,CAAC,CAAA;AACL,CAAC,CAAA;AAED,mBAAmB;AACnB,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAa,EAAE;IAC/C,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE;QACnD,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAa,EAAE;IACjD,OAAO,IAAI,QAAQ,CAAC,2BAA2B,EAAE;QAC/C,MAAM,EAAE,GAAG;QACX,OAAO,EAAE,EAAE,cAAc,EAAE,mBAAmB,EAAE,eAAe,EAAE,UAAU,EAAE;KAC9E,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,GAAa,EAAE;IAC5C,MAAM,IAAI,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC9B,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;QACxC,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,OAAe,EAAE,MAAM,GAAG,GAAG,EAAY,EAAE;IACvE,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE;QACtD,MAAM;QACN,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC,CAAA;AACJ,CAAC,CAAA"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"sync-provider.d.ts","sourceRoot":"","sources":["../src/sync-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,WAAW,EAAmB,MAAM,mBAAmB,CAAA;AAGpG,OAAO,EACL,KAAK,QAAQ,EAMb,QAAQ,EAKT,MAAM,yBAAyB,CAAA;
|
1
|
+
{"version":3,"file":"sync-provider.d.ts","sourceRoot":"","sources":["../src/sync-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,WAAW,EAAmB,MAAM,mBAAmB,CAAA;AAGpG,OAAO,EACL,KAAK,QAAQ,EAMb,QAAQ,EAKT,MAAM,yBAAyB,CAAA;AAKhC,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,gBAAgB,CAAC,CAAA;QAClD,yEAAyE;QACzE,IAAI,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;KACnD,CAAA;CACF;AAED,eAAO,MAAM,YAAY,2CAA6D,CAAA;AAEtF,eAAO,MAAM,eAAe,GACzB,wCAAwC,aAAa,KAAG,WAAW,CAAC,sBAAsB,CAAC,YAAY,CAoOpG,CAAA"}
|
package/dist/sync-provider.js
CHANGED
@@ -37,6 +37,7 @@ import { Effect, HttpClient, HttpClientRequest, HttpClientResponse, Option, Sche
|
|
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));
|
41
42
|
export const makeSyncBackend = ({ endpoint, ping: pingOptions, retry }) => ({ storeId, payload }) => Effect.gen(function* () {
|
42
43
|
const isConnected = yield* SubscriptionRef.make(false);
|
@@ -135,10 +136,41 @@ export const makeSyncBackend = ({ endpoint, ping: pingOptions, retry }) => ({ st
|
|
135
136
|
}));
|
136
137
|
}
|
137
138
|
},
|
138
|
-
push: (batch) =>
|
139
|
-
|
140
|
-
|
141
|
-
|
139
|
+
push: (batch) => Effect.gen(function* () {
|
140
|
+
const makeInvalidPushError = (cause) => {
|
141
|
+
if (cause instanceof InvalidPushError) {
|
142
|
+
return cause;
|
143
|
+
}
|
144
|
+
if (cause instanceof UnexpectedError) {
|
145
|
+
return new InvalidPushError({ cause });
|
146
|
+
}
|
147
|
+
if (cause instanceof S2LimitExceededError) {
|
148
|
+
const note = cause.limitType === 'record-metered-bytes'
|
149
|
+
? `S2 record exceeded ${cause.max} metered bytes (actual: ${cause.actual})`
|
150
|
+
: `S2 batch exceeded ${cause.max} (type: ${cause.limitType}, actual: ${cause.actual})`;
|
151
|
+
return new InvalidPushError({
|
152
|
+
cause: new UnexpectedError({
|
153
|
+
cause,
|
154
|
+
note,
|
155
|
+
payload: {
|
156
|
+
limitType: cause.limitType,
|
157
|
+
max: cause.max,
|
158
|
+
actual: cause.actual,
|
159
|
+
recordIndex: cause.recordIndex,
|
160
|
+
},
|
161
|
+
}),
|
162
|
+
});
|
163
|
+
}
|
164
|
+
return new InvalidPushError({ cause: new UnexpectedError({ cause }) });
|
165
|
+
};
|
166
|
+
const chunks = yield* Effect.sync(() => chunkEventsForS2(batch)).pipe(Effect.mapError(makeInvalidPushError));
|
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(makeInvalidPushError), 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,gBAAgB,EAAE,gBAAgB,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAEpG,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAEL,MAAM,EACN,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,MAAM,EACN,QAAQ,EACR,MAAM,EACN,GAAG,EACH,MAAM,EACN,eAAe,GAChB,MAAM,yBAAyB,CAAA;AAChC,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,KAAK,mBAAmB,MAAM,4BAA4B,CAAA;
|
1
|
+
{"version":3,"file":"sync-provider.js","sourceRoot":"","sources":["../src/sync-provider.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@livestore/sync-s2",
|
3
|
-
"version": "0.0.0-snapshot-
|
3
|
+
"version": "0.0.0-snapshot-4b42ef6ef0c52dda5b8633a10addf45134e4cafe",
|
4
4
|
"type": "module",
|
5
5
|
"sideEffects": false,
|
6
6
|
"exports": {
|
@@ -8,9 +8,9 @@
|
|
8
8
|
"./s2-proxy-helpers": "./dist/s2-proxy-helpers.js"
|
9
9
|
},
|
10
10
|
"dependencies": {
|
11
|
-
"@livestore/common": "0.0.0-snapshot-
|
12
|
-
"@livestore/utils": "0.0.0-snapshot-
|
13
|
-
"@livestore/livestore": "0.0.0-snapshot-
|
11
|
+
"@livestore/common": "0.0.0-snapshot-4b42ef6ef0c52dda5b8633a10addf45134e4cafe",
|
12
|
+
"@livestore/utils": "0.0.0-snapshot-4b42ef6ef0c52dda5b8633a10addf45134e4cafe",
|
13
|
+
"@livestore/livestore": "0.0.0-snapshot-4b42ef6ef0c52dda5b8633a10addf45134e4cafe"
|
14
14
|
},
|
15
15
|
"devDependencies": {},
|
16
16
|
"files": [
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import type { EventSequenceNumber, LiveStoreEvent } from '@livestore/common/schema'
|
2
|
+
import { describe, expect, it } from 'vitest'
|
3
|
+
import {
|
4
|
+
chunkEventsForS2,
|
5
|
+
computeRecordMeteredBytes,
|
6
|
+
MAX_BATCH_METERED_BYTES,
|
7
|
+
MAX_RECORD_METERED_BYTES,
|
8
|
+
S2LimitExceededError,
|
9
|
+
} from './limits.ts'
|
10
|
+
|
11
|
+
const encoder = new TextEncoder()
|
12
|
+
|
13
|
+
const makeEvent = (payloadLength: number, index = 0): LiveStoreEvent.AnyEncodedGlobal => ({
|
14
|
+
name: `event-${index}`,
|
15
|
+
args: { payload: 'x'.repeat(payloadLength) },
|
16
|
+
seqNum: index as EventSequenceNumber.GlobalEventSequenceNumber,
|
17
|
+
parentSeqNum: index as EventSequenceNumber.GlobalEventSequenceNumber,
|
18
|
+
clientId: 'client',
|
19
|
+
sessionId: 'session',
|
20
|
+
})
|
21
|
+
|
22
|
+
describe('S2 limits helpers', () => {
|
23
|
+
it('computes metered bytes for record bodies', () => {
|
24
|
+
const record = { body: JSON.stringify({ hello: 'world' }) }
|
25
|
+
const expected = 8 + encoder.encode(record.body ?? '').byteLength
|
26
|
+
expect(computeRecordMeteredBytes(record)).toBe(expected)
|
27
|
+
})
|
28
|
+
|
29
|
+
it('splits large batches while respecting metered byte limits', () => {
|
30
|
+
const events = [makeEvent(400_000, 1), makeEvent(400_000, 2), makeEvent(400_000, 3)]
|
31
|
+
const chunks = chunkEventsForS2(events)
|
32
|
+
|
33
|
+
expect(chunks).toHaveLength(2)
|
34
|
+
expect(chunks.map((chunk) => chunk.events.length)).toStrictEqual([2, 1])
|
35
|
+
expect(chunks.every((chunk) => chunk.meteredBytes <= MAX_BATCH_METERED_BYTES)).toBe(true)
|
36
|
+
})
|
37
|
+
|
38
|
+
it('throws when a single record exceeds the metered byte cap', () => {
|
39
|
+
const oversize = makeEvent(MAX_RECORD_METERED_BYTES, 1)
|
40
|
+
expect(() => chunkEventsForS2([oversize])).toThrow(S2LimitExceededError)
|
41
|
+
})
|
42
|
+
})
|