@livestore/sync-electric 0.4.0-dev.9 → 0.5.0-dev.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 +45 -50
- package/dist/api-schema.d.ts.map +1 -1
- package/dist/api-schema.js +14 -8
- package/dist/api-schema.js.map +1 -1
- package/dist/api-schema.test.d.ts +2 -0
- package/dist/api-schema.test.d.ts.map +1 -0
- package/dist/api-schema.test.js +42 -0
- package/dist/api-schema.test.js.map +1 -0
- package/dist/index.d.ts +49 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +74 -40
- package/dist/index.js.map +1 -1
- package/dist/make-electric-url.d.ts +22 -3
- package/dist/make-electric-url.d.ts.map +1 -1
- package/dist/make-electric-url.js +26 -7
- package/dist/make-electric-url.js.map +1 -1
- package/package.json +51 -12
- package/src/api-schema.test.ts +49 -0
- package/src/api-schema.ts +19 -11
- package/src/index.ts +92 -63
- package/src/make-electric-url.ts +28 -8
package/dist/api-schema.d.ts
CHANGED
|
@@ -1,60 +1,55 @@
|
|
|
1
1
|
import { Schema } from '@livestore/utils/effect';
|
|
2
2
|
export declare const PushPayload: Schema.Struct<{
|
|
3
|
-
_tag: Schema.tag<"@livestore/sync-electric.Push">;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
sessionId: typeof Schema.String;
|
|
3
|
+
readonly _tag: Schema.tag<"@livestore/sync-electric.Push">;
|
|
4
|
+
readonly storeId: Schema.String;
|
|
5
|
+
readonly batch: Schema.$Array<Schema.Struct<{
|
|
6
|
+
readonly name: Schema.String;
|
|
7
|
+
readonly args: Schema.Any;
|
|
8
|
+
readonly seqNum: Schema.brand<Schema.Int, "GlobalEventSequenceNumber">;
|
|
9
|
+
readonly parentSeqNum: Schema.brand<Schema.Int, "GlobalEventSequenceNumber">;
|
|
10
|
+
readonly clientId: Schema.String;
|
|
11
|
+
readonly sessionId: Schema.String;
|
|
13
12
|
}>>;
|
|
14
13
|
}>;
|
|
15
14
|
export declare const PullPayload: Schema.Struct<{
|
|
16
|
-
_tag: Schema.tag<"@livestore/sync-electric.Pull">;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
live: typeof Schema.Boolean;
|
|
15
|
+
readonly _tag: Schema.tag<"@livestore/sync-electric.Pull">;
|
|
16
|
+
readonly storeId: Schema.String;
|
|
17
|
+
readonly payload: Schema.optional<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
18
|
+
readonly handle: Schema.toCodecJson<Schema.Option<Schema.Struct<{
|
|
19
|
+
readonly offset: Schema.String;
|
|
20
|
+
readonly handle: Schema.String;
|
|
21
|
+
}>>>;
|
|
22
|
+
readonly live: Schema.Boolean;
|
|
25
23
|
}>;
|
|
26
|
-
export declare const ApiPayload: Schema.Union<[Schema.Struct<{
|
|
27
|
-
_tag: Schema.tag<"@livestore/sync-electric.Pull">;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
live: typeof Schema.Boolean;
|
|
24
|
+
export declare const ApiPayload: Schema.Union<readonly [Schema.Struct<{
|
|
25
|
+
readonly _tag: Schema.tag<"@livestore/sync-electric.Pull">;
|
|
26
|
+
readonly storeId: Schema.String;
|
|
27
|
+
readonly payload: Schema.optional<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
28
|
+
readonly handle: Schema.toCodecJson<Schema.Option<Schema.Struct<{
|
|
29
|
+
readonly offset: Schema.String;
|
|
30
|
+
readonly handle: Schema.String;
|
|
31
|
+
}>>>;
|
|
32
|
+
readonly live: Schema.Boolean;
|
|
36
33
|
}>, Schema.Struct<{
|
|
37
|
-
_tag: Schema.tag<"@livestore/sync-electric.Push">;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
sessionId: typeof Schema.String;
|
|
34
|
+
readonly _tag: Schema.tag<"@livestore/sync-electric.Push">;
|
|
35
|
+
readonly storeId: Schema.String;
|
|
36
|
+
readonly batch: Schema.$Array<Schema.Struct<{
|
|
37
|
+
readonly name: Schema.String;
|
|
38
|
+
readonly args: Schema.Any;
|
|
39
|
+
readonly seqNum: Schema.brand<Schema.Int, "GlobalEventSequenceNumber">;
|
|
40
|
+
readonly parentSeqNum: Schema.brand<Schema.Int, "GlobalEventSequenceNumber">;
|
|
41
|
+
readonly clientId: Schema.String;
|
|
42
|
+
readonly sessionId: Schema.String;
|
|
47
43
|
}>>;
|
|
48
44
|
}>]>;
|
|
49
|
-
export declare const ArgsSchema: Schema.
|
|
50
|
-
_tag: Schema.tag<"@livestore/sync-electric.Pull">;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}>>>;
|
|
45
|
+
export declare const ArgsSchema: Schema.compose<Schema.fromJsonString<Schema.Struct<{
|
|
46
|
+
readonly _tag: Schema.tag<"@livestore/sync-electric.Pull">;
|
|
47
|
+
readonly storeId: Schema.String;
|
|
48
|
+
readonly payload: Schema.optional<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
49
|
+
readonly handle: Schema.toCodecJson<Schema.Option<Schema.Struct<{
|
|
50
|
+
readonly offset: Schema.String;
|
|
51
|
+
readonly handle: Schema.String;
|
|
52
|
+
}>>>;
|
|
53
|
+
readonly live: Schema.Boolean;
|
|
54
|
+
}>>, Schema.StringFromUriComponent>;
|
|
60
55
|
//# sourceMappingURL=api-schema.d.ts.map
|
package/dist/api-schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-schema.d.ts","sourceRoot":"","sources":["../src/api-schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEhD,eAAO,MAAM,WAAW
|
|
1
|
+
{"version":3,"file":"api-schema.d.ts","sourceRoot":"","sources":["../src/api-schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEhD,eAAO,MAAM,WAAW;;;;;;;;;;;EAGsC,CAAA;AAE9D,eAAO,MAAM,WAAW;;;;;;;;;EAkBsC,CAAA;AAE9D,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;IAA2C,CAAA;AAGlE,eAAO,MAAM,UAAU;;;;;;;;;mCAA0F,CAAA"}
|
package/dist/api-schema.js
CHANGED
|
@@ -2,18 +2,24 @@ import { LiveStoreEvent } from '@livestore/common/schema';
|
|
|
2
2
|
import { Schema } from '@livestore/utils/effect';
|
|
3
3
|
export const PushPayload = Schema.TaggedStruct('@livestore/sync-electric.Push', {
|
|
4
4
|
storeId: Schema.String,
|
|
5
|
-
batch: Schema.Array(LiveStoreEvent.
|
|
6
|
-
}).
|
|
5
|
+
batch: Schema.Array(LiveStoreEvent.Global.Encoded),
|
|
6
|
+
}).annotate({ title: '@livestore/sync-electric.PushPayload' });
|
|
7
7
|
export const PullPayload = Schema.TaggedStruct('@livestore/sync-electric.Pull', {
|
|
8
8
|
storeId: Schema.String,
|
|
9
|
-
payload
|
|
10
|
-
|
|
9
|
+
// `optional` so an absent payload is omitted from the JSON entirely (a required key with an
|
|
10
|
+
// `undefined` value would be dropped by `JSON.stringify` and then fail decoding as "Missing key").
|
|
11
|
+
payload: Schema.optional(Schema.Json),
|
|
12
|
+
// `toCodecJson` makes the `Option` encode to its JSON-safe struct form (`{ _tag: "None" }` /
|
|
13
|
+
// `{ _tag: "Some", value }`). A bare `Schema.Option` encodes to a runtime `Option`, whose
|
|
14
|
+
// `toJSON` leaks `{"_id":"Option",...}` when `fromJsonString` runs `JSON.stringify`, and that
|
|
15
|
+
// shape then fails to decode back into an `Option`.
|
|
16
|
+
handle: Schema.toCodecJson(Schema.Option(Schema.Struct({
|
|
11
17
|
offset: Schema.String,
|
|
12
18
|
handle: Schema.String,
|
|
13
|
-
})),
|
|
19
|
+
}))),
|
|
14
20
|
live: Schema.Boolean,
|
|
15
|
-
}).
|
|
16
|
-
export const ApiPayload = Schema.Union(PullPayload, PushPayload);
|
|
21
|
+
}).annotate({ title: '@livestore/sync-electric.PullPayload' });
|
|
22
|
+
export const ApiPayload = Schema.Union([PullPayload, PushPayload]);
|
|
17
23
|
// Format for the query params
|
|
18
|
-
export const ArgsSchema = Schema.
|
|
24
|
+
export const ArgsSchema = Schema.StringFromUriComponent.pipe(Schema.decodeTo(Schema.fromJsonString(PullPayload)));
|
|
19
25
|
//# sourceMappingURL=api-schema.js.map
|
package/dist/api-schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-schema.js","sourceRoot":"","sources":["../src/api-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEhD,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC,+BAA+B,EAAE;IAC9E,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"api-schema.js","sourceRoot":"","sources":["../src/api-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEhD,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC,+BAA+B,EAAE;IAC9E,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC;CACnD,CAAC,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,sCAAsC,EAAE,CAAC,CAAA;AAE9D,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC,+BAA+B,EAAE;IAC9E,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,4FAA4F;IAC5F,mGAAmG;IACnG,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;IACrC,6FAA6F;IAC7F,0FAA0F;IAC1F,8FAA8F;IAC9F,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC,WAAW,CACxB,MAAM,CAAC,MAAM,CACX,MAAM,CAAC,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC,CACH,CACF;IACD,IAAI,EAAE,MAAM,CAAC,OAAO;CACrB,CAAC,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,sCAAsC,EAAE,CAAC,CAAA;AAE9D,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAA;AAElE,8BAA8B;AAC9B,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,sBAAsB,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-schema.test.d.ts","sourceRoot":"","sources":["../src/api-schema.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Option, Schema } from '@livestore/utils/effect';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import * as ApiSchema from "./api-schema.js";
|
|
4
|
+
import { makeElectricUrl } from "./make-electric-url.js";
|
|
5
|
+
const HandleStruct = { offset: 'off-1', handle: 'h-1' };
|
|
6
|
+
const cases = [
|
|
7
|
+
{ name: 'none + no payload', storeId: 's1', payload: undefined, handle: Option.none(), live: false },
|
|
8
|
+
{ name: 'some + payload', storeId: 's2', payload: { foo: 'bar' }, handle: Option.some(HandleStruct), live: true },
|
|
9
|
+
{ name: 'none + payload present', storeId: 's3', payload: { a: 1 }, handle: Option.none(), live: false },
|
|
10
|
+
{ name: 'some + no payload', storeId: 's4', payload: undefined, handle: Option.some(HandleStruct), live: true },
|
|
11
|
+
{ name: 'none + null payload', storeId: 's5', payload: null, handle: Option.none(), live: false },
|
|
12
|
+
];
|
|
13
|
+
describe('sync-electric ArgsSchema round-trip', () => {
|
|
14
|
+
for (const c of cases) {
|
|
15
|
+
it(`round-trips ${c.name}`, () => {
|
|
16
|
+
const input = ApiSchema.PullPayload.make({
|
|
17
|
+
storeId: c.storeId,
|
|
18
|
+
payload: c.payload,
|
|
19
|
+
handle: c.handle,
|
|
20
|
+
live: c.live,
|
|
21
|
+
});
|
|
22
|
+
const encoded = Schema.encodeSync(ApiSchema.ArgsSchema)(input);
|
|
23
|
+
expect(typeof encoded).toBe('string');
|
|
24
|
+
const decoded = Schema.decodeUnknownSync(ApiSchema.ArgsSchema)(encoded);
|
|
25
|
+
expect(Option.isOption(decoded.handle)).toBe(true);
|
|
26
|
+
expect(decoded.handle._tag).toBe(c.handle._tag);
|
|
27
|
+
if (Option.isSome(c.handle)) {
|
|
28
|
+
expect(decoded.handle.value).toEqual(HandleStruct);
|
|
29
|
+
}
|
|
30
|
+
expect(decoded.payload).toEqual(c.payload);
|
|
31
|
+
expect(decoded.storeId).toBe(c.storeId);
|
|
32
|
+
expect(decoded.live).toBe(c.live);
|
|
33
|
+
// Full path through makeElectricUrl: URLSearchParams -> Struct({ args }) -> ArgsSchema
|
|
34
|
+
const searchParams = new URLSearchParams({ args: encoded });
|
|
35
|
+
const result = makeElectricUrl({ electricHost: 'http://electric.test', searchParams });
|
|
36
|
+
expect(result.storeId).toBe(c.storeId);
|
|
37
|
+
expect(result.needsInit).toBe(Option.isNone(c.handle));
|
|
38
|
+
expect(result.payload).toEqual(c.payload);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
//# sourceMappingURL=api-schema.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-schema.test.js","sourceRoot":"","sources":["../src/api-schema.test.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { SyncBackend } from '@livestore/common';
|
|
2
2
|
import { type Duration, Schema } from '@livestore/utils/effect';
|
|
3
|
-
declare const InvalidOperationError_base: Schema.
|
|
4
|
-
readonly
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
message: typeof Schema.String;
|
|
8
|
-
}>;
|
|
3
|
+
declare const InvalidOperationError_base: Schema.Class<InvalidOperationError, Schema.TaggedStruct<"InvalidOperationError", {
|
|
4
|
+
readonly operation: Schema.Literals<readonly ["delete", "update"]>;
|
|
5
|
+
readonly message: Schema.String;
|
|
6
|
+
}>, import("effect/Cause").YieldableError>;
|
|
9
7
|
export declare class InvalidOperationError extends InvalidOperationError_base {
|
|
10
8
|
}
|
|
11
9
|
export * as ApiSchema from './api-schema.ts';
|
|
@@ -34,18 +32,59 @@ export interface SyncBackendOptions {
|
|
|
34
32
|
* How long to wait for a ping response before timing out
|
|
35
33
|
* @default 10 seconds
|
|
36
34
|
*/
|
|
37
|
-
requestTimeout?: Duration.
|
|
35
|
+
requestTimeout?: Duration.Input;
|
|
38
36
|
/**
|
|
39
37
|
* How often to send ping requests
|
|
40
38
|
* @default 10 seconds
|
|
41
39
|
*/
|
|
42
|
-
requestInterval?: Duration.
|
|
40
|
+
requestInterval?: Duration.Input;
|
|
43
41
|
};
|
|
44
42
|
}
|
|
45
43
|
export declare const SyncMetadata: Schema.Struct<{
|
|
46
|
-
offset:
|
|
47
|
-
handle:
|
|
44
|
+
readonly offset: Schema.String;
|
|
45
|
+
readonly handle: Schema.String;
|
|
48
46
|
}>;
|
|
49
47
|
export type SyncMetadata = typeof SyncMetadata.Type;
|
|
48
|
+
/**
|
|
49
|
+
* Creates a sync backend that uses ElectricSQL for real-time event synchronization.
|
|
50
|
+
*
|
|
51
|
+
* ElectricSQL enables real-time sync by streaming PostgreSQL changes to clients.
|
|
52
|
+
* This backend handles push (inserting events) and pull (streaming events via Electric's
|
|
53
|
+
* shape-based sync protocol).
|
|
54
|
+
*
|
|
55
|
+
* The endpoint should typically be part of your API layer to handle authentication,
|
|
56
|
+
* rate limiting, and proxying requests to the Electric server.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* import { makeSyncBackend } from '@livestore/sync-electric'
|
|
61
|
+
*
|
|
62
|
+
* const adapter = makePersistedAdapter({
|
|
63
|
+
* sync: {
|
|
64
|
+
* backend: makeSyncBackend({
|
|
65
|
+
* endpoint: '/api/electric',
|
|
66
|
+
* }),
|
|
67
|
+
* },
|
|
68
|
+
* })
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* // With separate endpoints for push/pull/ping
|
|
74
|
+
* const backend = makeSyncBackend({
|
|
75
|
+
* endpoint: {
|
|
76
|
+
* push: '/api/push-event',
|
|
77
|
+
* pull: '/api/pull-events',
|
|
78
|
+
* ping: '/api/ping',
|
|
79
|
+
* },
|
|
80
|
+
* ping: {
|
|
81
|
+
* enabled: true,
|
|
82
|
+
* requestInterval: 15_000, // 15 seconds
|
|
83
|
+
* },
|
|
84
|
+
* })
|
|
85
|
+
* ```
|
|
86
|
+
*
|
|
87
|
+
* @see https://livestore.dev/docs/sync/electric for setup guide
|
|
88
|
+
*/
|
|
50
89
|
export declare const makeSyncBackend: ({ endpoint, ...options }: SyncBackendOptions) => SyncBackend.SyncBackendConstructor<SyncMetadata>;
|
|
51
90
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,WAAW,EAAgB,MAAM,mBAAmB,CAAA;AAGlF,OAAO,EACL,KAAK,QAAQ,EASb,MAAM,EAGP,MAAM,yBAAyB,CAAA;;;;;AAIhC,qBAAa,qBAAsB,SAAQ,0BAKzC;CAAG;AAEL,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAA;AAC5C,cAAc,wBAAwB,CAAA;AAkFtC,eAAO,MAAM,kBAAkB,GAAI,QAAQ,SAAS,kBAAkB,EAAE,SAAS,QAAQ,aAAY,CAAA;AAErG,MAAM,WAAW,kBAAkB;IACjC;;;;;;;OAOG;IACH,QAAQ,EACJ,MAAM,GACN;QACE,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;IAEL,IAAI,CAAC,EAAE;QACL;;WAEG;QACH,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB;;;WAGG;QACH,cAAc,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAA;QAC/B;;;WAGG;QACH,eAAe,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAA;KACjC,CAAA;CACF;AAED,eAAO,MAAM,YAAY;;;EAIvB,CAAA;AAEF,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,eAAO,MAAM,eAAe,GACzB,0BAA0B,kBAAkB,KAAG,WAAW,CAAC,sBAAsB,CAAC,YAAY,CAuM3F,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SyncBackend, UnknownError } from '@livestore/common';
|
|
2
2
|
import { LiveStoreEvent } from '@livestore/common/schema';
|
|
3
3
|
import { notYetImplemented } from '@livestore/utils';
|
|
4
|
-
import { Effect, HttpClient, HttpClientRequest, HttpClientResponse, Option, ReadonlyArray, Schedule, Schema, Stream, SubscriptionRef, } from '@livestore/utils/effect';
|
|
4
|
+
import { Effect, HttpClient, HttpClientRequest, HttpClientResponse, Option, ReadonlyArray, Result, Schedule, Schema, Stream, SubscriptionRef, } from '@livestore/utils/effect';
|
|
5
5
|
import * as ApiSchema from "./api-schema.js";
|
|
6
|
-
export class InvalidOperationError extends Schema.TaggedError()('InvalidOperationError', {
|
|
7
|
-
operation: Schema.
|
|
6
|
+
export class InvalidOperationError extends Schema.TaggedError('~@livestore/sync-electric/InvalidOperationError')('InvalidOperationError', {
|
|
7
|
+
operation: Schema.Literals(['delete', 'update']),
|
|
8
8
|
message: Schema.String,
|
|
9
9
|
}) {
|
|
10
10
|
}
|
|
@@ -53,33 +53,30 @@ const LiveStoreEventGlobalFromStringRecord = Schema.Struct({
|
|
|
53
53
|
seqNum: Schema.NumberFromString,
|
|
54
54
|
parentSeqNum: Schema.NumberFromString,
|
|
55
55
|
name: Schema.String,
|
|
56
|
-
args: Schema.
|
|
56
|
+
args: Schema.fromJsonString(Schema.Any),
|
|
57
57
|
clientId: Schema.String,
|
|
58
58
|
sessionId: Schema.String,
|
|
59
59
|
})
|
|
60
|
-
.pipe(Schema.
|
|
61
|
-
|
|
62
|
-
encode: (_) => _,
|
|
63
|
-
}))
|
|
64
|
-
.annotations({ title: '@livestore/sync-electric:LiveStoreEventGlobalFromStringRecord' });
|
|
60
|
+
.pipe(Schema.decodeTo(LiveStoreEvent.Global.Encoded))
|
|
61
|
+
.annotate({ title: '@livestore/sync-electric:LiveStoreEventGlobalFromStringRecord' });
|
|
65
62
|
const ResponseItemInsert = Schema.Struct({
|
|
66
63
|
/** Postgres path (e.g. `"public"."events_9069baf0_b3e6_42f7_980f_188416eab3fx3"/"0"`) */
|
|
67
64
|
key: Schema.optional(Schema.String),
|
|
68
65
|
value: LiveStoreEventGlobalFromStringRecord,
|
|
69
66
|
headers: Schema.Struct({ operation: Schema.Literal('insert'), relation: Schema.Array(Schema.String) }),
|
|
70
|
-
}).
|
|
67
|
+
}).annotate({ title: '@livestore/sync-electric:ResponseItemInsert' });
|
|
71
68
|
const ResponseItemInvalid = Schema.Struct({
|
|
72
69
|
/** Postgres path (e.g. `"public"."events_9069baf0_b3e6_42f7_980f_188416eab3fx3"/"0"`) */
|
|
73
70
|
key: Schema.optional(Schema.String),
|
|
74
71
|
value: Schema.Any,
|
|
75
|
-
headers: Schema.Struct({ operation: Schema.
|
|
76
|
-
}).
|
|
72
|
+
headers: Schema.Struct({ operation: Schema.Literals(['update', 'delete']), relation: Schema.Array(Schema.String) }),
|
|
73
|
+
}).annotate({ title: '@livestore/sync-electric:ResponseItemInvalid' });
|
|
77
74
|
const ResponseItemControl = Schema.Struct({
|
|
78
75
|
key: Schema.optional(Schema.String),
|
|
79
76
|
value: Schema.optional(Schema.Any),
|
|
80
77
|
headers: Schema.Struct({ control: Schema.String }),
|
|
81
|
-
}).
|
|
82
|
-
const ResponseItem = Schema.Union(ResponseItemInsert, ResponseItemInvalid, ResponseItemControl);
|
|
78
|
+
}).annotate({ title: '@livestore/sync-electric:ResponseItemControl' });
|
|
79
|
+
const ResponseItem = Schema.Union([ResponseItemInsert, ResponseItemInvalid, ResponseItemControl]);
|
|
83
80
|
const ResponseHeaders = Schema.Struct({
|
|
84
81
|
'electric-handle': Schema.String,
|
|
85
82
|
// 'electric-schema': Schema.parseJson(Schema.Any),
|
|
@@ -92,6 +89,47 @@ export const SyncMetadata = Schema.Struct({
|
|
|
92
89
|
// TODO move this into some kind of "global" sync metadata as it's the same for each event
|
|
93
90
|
handle: Schema.String,
|
|
94
91
|
});
|
|
92
|
+
/**
|
|
93
|
+
* Creates a sync backend that uses ElectricSQL for real-time event synchronization.
|
|
94
|
+
*
|
|
95
|
+
* ElectricSQL enables real-time sync by streaming PostgreSQL changes to clients.
|
|
96
|
+
* This backend handles push (inserting events) and pull (streaming events via Electric's
|
|
97
|
+
* shape-based sync protocol).
|
|
98
|
+
*
|
|
99
|
+
* The endpoint should typically be part of your API layer to handle authentication,
|
|
100
|
+
* rate limiting, and proxying requests to the Electric server.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* import { makeSyncBackend } from '@livestore/sync-electric'
|
|
105
|
+
*
|
|
106
|
+
* const adapter = makePersistedAdapter({
|
|
107
|
+
* sync: {
|
|
108
|
+
* backend: makeSyncBackend({
|
|
109
|
+
* endpoint: '/api/electric',
|
|
110
|
+
* }),
|
|
111
|
+
* },
|
|
112
|
+
* })
|
|
113
|
+
* ```
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* // With separate endpoints for push/pull/ping
|
|
118
|
+
* const backend = makeSyncBackend({
|
|
119
|
+
* endpoint: {
|
|
120
|
+
* push: '/api/push-event',
|
|
121
|
+
* pull: '/api/pull-events',
|
|
122
|
+
* ping: '/api/ping',
|
|
123
|
+
* },
|
|
124
|
+
* ping: {
|
|
125
|
+
* enabled: true,
|
|
126
|
+
* requestInterval: 15_000, // 15 seconds
|
|
127
|
+
* },
|
|
128
|
+
* })
|
|
129
|
+
* ```
|
|
130
|
+
*
|
|
131
|
+
* @see https://livestore.dev/docs/sync/electric for setup guide
|
|
132
|
+
*/
|
|
95
133
|
export const makeSyncBackend = ({ endpoint, ...options }) => ({ storeId, payload }) => Effect.gen(function* () {
|
|
96
134
|
const isConnected = yield* SubscriptionRef.make(false);
|
|
97
135
|
const pullEndpoint = typeof endpoint === 'string' ? endpoint : endpoint.pull;
|
|
@@ -99,12 +137,12 @@ export const makeSyncBackend = ({ endpoint, ...options }) => ({ storeId, payload
|
|
|
99
137
|
const pingEndpoint = typeof endpoint === 'string' ? endpoint : endpoint.ping;
|
|
100
138
|
const httpClient = yield* HttpClient.HttpClient;
|
|
101
139
|
const runPull = (handle, { live }) => Effect.gen(function* () {
|
|
102
|
-
const argsJson = yield* Schema.
|
|
140
|
+
const argsJson = yield* Schema.encodeEffect(ApiSchema.ArgsSchema)(ApiSchema.PullPayload.make({ storeId, handle, payload, live }));
|
|
103
141
|
const url = `${pullEndpoint}?args=${argsJson}`;
|
|
104
142
|
const resp = yield* httpClient.get(url);
|
|
105
143
|
if (resp.status === 401) {
|
|
106
|
-
const body = yield* resp.text.pipe(Effect.
|
|
107
|
-
return yield*
|
|
144
|
+
const body = yield* resp.text.pipe(Effect.catch(() => Effect.succeed('-')));
|
|
145
|
+
return yield* new UnknownError({
|
|
108
146
|
cause: new Error(`Unauthorized (401): Couldn't connect to ElectricSQL: ${body}`),
|
|
109
147
|
});
|
|
110
148
|
}
|
|
@@ -127,9 +165,7 @@ export const makeSyncBackend = ({ endpoint, ...options }) => ({ storeId, payload
|
|
|
127
165
|
}
|
|
128
166
|
else if (resp.status < 200 || resp.status >= 300) {
|
|
129
167
|
const body = yield* resp.text;
|
|
130
|
-
return yield*
|
|
131
|
-
cause: new Error(`Unexpected status code: ${resp.status}: ${body}`),
|
|
132
|
-
});
|
|
168
|
+
return yield* new UnknownError({ cause: new Error(`Unexpected status code: ${resp.status}: ${body}`) });
|
|
133
169
|
}
|
|
134
170
|
const headers = yield* HttpClientResponse.schemaHeaders(ResponseHeaders)(resp);
|
|
135
171
|
const nextHandle = {
|
|
@@ -145,7 +181,7 @@ export const makeSyncBackend = ({ endpoint, ...options }) => ({ storeId, payload
|
|
|
145
181
|
onExcessProperty: 'preserve',
|
|
146
182
|
})(resp);
|
|
147
183
|
// Check for delete/update operations and throw descriptive error
|
|
148
|
-
const invalidOperations = ReadonlyArray.filterMap(allItems, (item) => Schema.is(ResponseItemInvalid)(item) ?
|
|
184
|
+
const invalidOperations = ReadonlyArray.filterMap(allItems, (item) => Schema.is(ResponseItemInvalid)(item) === true ? Result.succeed(item.headers.operation) : Result.failVoid);
|
|
149
185
|
if (invalidOperations.length > 0) {
|
|
150
186
|
const operation = invalidOperations[0];
|
|
151
187
|
return yield* new InvalidOperationError({
|
|
@@ -159,14 +195,14 @@ export const makeSyncBackend = ({ endpoint, ...options }) => ({ storeId, payload
|
|
|
159
195
|
}));
|
|
160
196
|
yield* Effect.annotateCurrentSpan({ itemsCount: items.length, nextHandle });
|
|
161
197
|
return Option.some([items, Option.some(nextHandle)]);
|
|
162
|
-
}).pipe(Effect.scoped, Effect.mapError((cause) => (cause
|
|
198
|
+
}).pipe(Effect.scoped, Effect.mapError((cause) => (Schema.is(UnknownError)(cause) === true ? cause : new UnknownError({ cause }))), Effect.withSpan('electric-provider:runPull', { attributes: { handle, live } }));
|
|
163
199
|
const pullEndpointHasSameOrigin = pullEndpoint.startsWith('/') ||
|
|
164
200
|
(globalThis.location !== undefined && globalThis.location.origin === new URL(pullEndpoint).origin);
|
|
165
201
|
const pingTimeout = options.ping?.requestTimeout ?? 10_000;
|
|
166
202
|
const ping = Effect.gen(function* () {
|
|
167
203
|
yield* httpClient.pipe(HttpClient.filterStatusOk).head(pingEndpoint);
|
|
168
204
|
yield* SubscriptionRef.set(isConnected, true);
|
|
169
|
-
}).pipe(
|
|
205
|
+
}).pipe(UnknownError.mapToUnknownError, Effect.timeout(pingTimeout), Effect.catchTag('TimeoutError', () => SubscriptionRef.set(isConnected, false)), Effect.withSpan('electric-provider:ping'));
|
|
170
206
|
const pingInterval = options.ping?.requestInterval ?? 10_000;
|
|
171
207
|
if (options.ping?.enabled !== false) {
|
|
172
208
|
// Automatically ping the server to keep the connection alive
|
|
@@ -174,41 +210,39 @@ export const makeSyncBackend = ({ endpoint, ...options }) => ({ storeId, payload
|
|
|
174
210
|
}
|
|
175
211
|
// If the pull endpoint has the same origin as the current page, we can assume that we already have a connection
|
|
176
212
|
// otherwise we send a HEAD request to speed up the connection process
|
|
177
|
-
const connect = pullEndpointHasSameOrigin
|
|
178
|
-
? Effect.void
|
|
179
|
-
: ping.pipe(UnexpectedError.mapToUnexpectedError);
|
|
213
|
+
const connect = pullEndpointHasSameOrigin === true ? Effect.void : ping.pipe(UnknownError.mapToUnknownError);
|
|
180
214
|
return SyncBackend.of({
|
|
181
215
|
connect,
|
|
182
216
|
pull: (cursor, options) => {
|
|
183
217
|
let hasEmittedAtLeastOnce = false;
|
|
184
|
-
return Stream.
|
|
218
|
+
return Stream.unfold(cursor.pipe(Option.flatMap((_) => _.metadata)), (metadataOption) => Effect.gen(function* () {
|
|
185
219
|
const result = yield* runPull(metadataOption, { live: options?.live ?? false });
|
|
186
|
-
if (Option.isNone(result))
|
|
187
|
-
return
|
|
220
|
+
if (Option.isNone(result) === true)
|
|
221
|
+
return undefined;
|
|
188
222
|
const [batch, nextMetadataOption] = result.value;
|
|
189
223
|
// Continue pagination if we have data
|
|
190
224
|
if (batch.length > 0) {
|
|
191
225
|
hasEmittedAtLeastOnce = true;
|
|
192
|
-
return
|
|
226
|
+
return [{ batch, hasMore: true }, nextMetadataOption];
|
|
193
227
|
}
|
|
194
228
|
// Make sure we emit at least once even if there's no data or we're live-pulling
|
|
195
|
-
if (hasEmittedAtLeastOnce === false || options?.live) {
|
|
229
|
+
if (hasEmittedAtLeastOnce === false || options?.live === true) {
|
|
196
230
|
hasEmittedAtLeastOnce = true;
|
|
197
|
-
return
|
|
231
|
+
return [{ batch, hasMore: false }, nextMetadataOption];
|
|
198
232
|
}
|
|
199
233
|
// Stop on empty batch (when not live)
|
|
200
|
-
return
|
|
234
|
+
return undefined;
|
|
201
235
|
})).pipe(Stream.map(({ batch, hasMore }) => ({
|
|
202
236
|
batch,
|
|
203
|
-
pageInfo: hasMore ? SyncBackend.pageInfoMoreUnknown : SyncBackend.pageInfoNoMore,
|
|
237
|
+
pageInfo: hasMore === true ? SyncBackend.pageInfoMoreUnknown : SyncBackend.pageInfoNoMore,
|
|
204
238
|
})), Stream.withSpan('electric-provider:pull'));
|
|
205
239
|
},
|
|
206
|
-
push:
|
|
207
|
-
const resp = yield* HttpClientRequest.schemaBodyJson(ApiSchema.PushPayload)(HttpClientRequest.post(pushEndpoint), ApiSchema.PushPayload.make({ storeId, batch })).pipe(Effect.andThen(httpClient.pipe(HttpClient.filterStatusOk).execute), Effect.andThen(HttpClientResponse.schemaBodyJson(Schema.Struct({ success: Schema.Boolean }))), Effect.scoped, Effect.mapError((cause) =>
|
|
208
|
-
if (
|
|
209
|
-
return yield*
|
|
240
|
+
push: Effect.fn('electric-provider:push')(function* (batch) {
|
|
241
|
+
const resp = yield* HttpClientRequest.schemaBodyJson(ApiSchema.PushPayload)(HttpClientRequest.post(pushEndpoint), ApiSchema.PushPayload.make({ storeId, batch })).pipe(Effect.andThen(httpClient.pipe(HttpClient.filterStatusOk).execute), Effect.andThen(HttpClientResponse.schemaBodyJson(Schema.Struct({ success: Schema.Boolean }))), Effect.scoped, Effect.mapError((cause) => UnknownError.make({ cause })));
|
|
242
|
+
if (resp.success === false) {
|
|
243
|
+
return yield* new UnknownError({ cause: new Error('Push failed') });
|
|
210
244
|
}
|
|
211
|
-
})
|
|
245
|
+
}),
|
|
212
246
|
ping,
|
|
213
247
|
isConnected,
|
|
214
248
|
metadata: {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,13 +30,32 @@ export declare const makeElectricUrl: ({ electricHost, searchParams: providedSea
|
|
|
30
30
|
*/
|
|
31
31
|
needsInit: boolean;
|
|
32
32
|
/** Sync payload provided by the client */
|
|
33
|
-
payload: Schema.
|
|
33
|
+
payload: Schema.Json | undefined;
|
|
34
34
|
};
|
|
35
35
|
export declare const toTableName: (storeId: string) => string;
|
|
36
36
|
/**
|
|
37
|
-
*
|
|
37
|
+
* CRITICAL: Increment this version whenever you modify the Postgres table schema structure.
|
|
38
38
|
*
|
|
39
|
-
*
|
|
39
|
+
* Bump required when:
|
|
40
|
+
* - Adding/removing/renaming columns in the eventlog table (see examples/web-todomvc-sync-electric/src/server/db.ts)
|
|
41
|
+
* - Changing column types or constraints
|
|
42
|
+
* - Modifying primary keys or indexes
|
|
43
|
+
*
|
|
44
|
+
* Bump NOT required when:
|
|
45
|
+
* - Changing query patterns or fetch logic
|
|
46
|
+
* - Adding new tables (as long as existing table schema remains unchanged)
|
|
47
|
+
* - Updating client-side implementation details
|
|
48
|
+
*
|
|
49
|
+
* Impact: Changing this version triggers a "soft reset" - new table names are created
|
|
50
|
+
* and old data becomes inaccessible (but remains in the database).
|
|
51
|
+
*
|
|
52
|
+
* Current schema (PostgreSQL):
|
|
53
|
+
* - seqNum (INTEGER PRIMARY KEY)
|
|
54
|
+
* - parentSeqNum (INTEGER)
|
|
55
|
+
* - name (TEXT NOT NULL)
|
|
56
|
+
* - args (JSONB NOT NULL)
|
|
57
|
+
* - clientId (TEXT NOT NULL)
|
|
58
|
+
* - sessionId (TEXT NOT NULL)
|
|
40
59
|
*/
|
|
41
60
|
export declare const PERSISTENCE_FORMAT_VERSION = 6;
|
|
42
61
|
//# sourceMappingURL=make-electric-url.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"make-electric-url.d.ts","sourceRoot":"","sources":["../src/make-electric-url.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"make-electric-url.d.ts","sourceRoot":"","sources":["../src/make-electric-url.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAI9D;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,0FAM7B;IACD,YAAY,EAAE,MAAM,CAAA;IACpB;;;;;OAKG;IACH,YAAY,EAAE,eAAe,CAAA;IAC7B,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,gCAAgC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,KAAG;IACF;;OAEG;IACH,GAAG,EAAE,MAAM,CAAA;IACX,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,SAAS,EAAE,OAAO,CAAA;IAClB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC,IAAI,GAAG,SAAS,CAAA;CA4CjC,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,SAAS,MAAM,WAe1C,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,0BAA0B,IAAI,CAAA"}
|