@livestore/sync-cf 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/README.md +7 -8
- package/dist/.tsbuildinfo +1 -1
- package/dist/cf-worker/do/durable-object.d.ts +1 -1
- package/dist/cf-worker/do/durable-object.d.ts.map +1 -1
- package/dist/cf-worker/do/durable-object.js +13 -8
- package/dist/cf-worker/do/durable-object.js.map +1 -1
- package/dist/cf-worker/do/layer.d.ts +5 -5
- package/dist/cf-worker/do/layer.d.ts.map +1 -1
- package/dist/cf-worker/do/layer.js +32 -9
- package/dist/cf-worker/do/layer.js.map +1 -1
- package/dist/cf-worker/do/pull.d.ts +7 -2
- package/dist/cf-worker/do/pull.d.ts.map +1 -1
- package/dist/cf-worker/do/pull.js +16 -10
- package/dist/cf-worker/do/pull.js.map +1 -1
- package/dist/cf-worker/do/push.d.ts +5 -4
- package/dist/cf-worker/do/push.d.ts.map +1 -1
- package/dist/cf-worker/do/push.js +25 -17
- package/dist/cf-worker/do/push.js.map +1 -1
- package/dist/cf-worker/do/sqlite.d.ts +10 -1
- package/dist/cf-worker/do/sqlite.d.ts.map +1 -1
- package/dist/cf-worker/do/sqlite.js +13 -4
- package/dist/cf-worker/do/sqlite.js.map +1 -1
- package/dist/cf-worker/do/sync-storage.d.ts +14 -9
- package/dist/cf-worker/do/sync-storage.d.ts.map +1 -1
- package/dist/cf-worker/do/sync-storage.js +92 -18
- package/dist/cf-worker/do/sync-storage.js.map +1 -1
- package/dist/cf-worker/do/transport/do-rpc-server.d.ts.map +1 -1
- package/dist/cf-worker/do/transport/do-rpc-server.js +13 -7
- package/dist/cf-worker/do/transport/do-rpc-server.js.map +1 -1
- package/dist/cf-worker/do/transport/http-rpc-server.d.ts +4 -2
- package/dist/cf-worker/do/transport/http-rpc-server.d.ts.map +1 -1
- package/dist/cf-worker/do/transport/http-rpc-server.js +24 -15
- package/dist/cf-worker/do/transport/http-rpc-server.js.map +1 -1
- package/dist/cf-worker/do/transport/ws-rpc-server.d.ts +2 -1
- package/dist/cf-worker/do/transport/ws-rpc-server.d.ts.map +1 -1
- package/dist/cf-worker/do/transport/ws-rpc-server.js +30 -8
- package/dist/cf-worker/do/transport/ws-rpc-server.js.map +1 -1
- package/dist/cf-worker/shared.d.ts +118 -31
- package/dist/cf-worker/shared.d.ts.map +1 -1
- package/dist/cf-worker/shared.js +40 -7
- package/dist/cf-worker/shared.js.map +1 -1
- package/dist/cf-worker/worker.d.ts +46 -38
- package/dist/cf-worker/worker.d.ts.map +1 -1
- package/dist/cf-worker/worker.js +51 -34
- package/dist/cf-worker/worker.js.map +1 -1
- package/dist/client/transport/do-rpc-client.d.ts.map +1 -1
- package/dist/client/transport/do-rpc-client.js +27 -10
- package/dist/client/transport/do-rpc-client.js.map +1 -1
- package/dist/client/transport/http-rpc-client.d.ts.map +1 -1
- package/dist/client/transport/http-rpc-client.js +29 -9
- package/dist/client/transport/http-rpc-client.js.map +1 -1
- package/dist/client/transport/ws-rpc-client.d.ts +2 -1
- package/dist/client/transport/ws-rpc-client.d.ts.map +1 -1
- package/dist/client/transport/ws-rpc-client.js +31 -17
- package/dist/client/transport/ws-rpc-client.js.map +1 -1
- package/dist/common/constants.d.ts +7 -0
- package/dist/common/constants.d.ts.map +1 -0
- package/dist/common/constants.js +17 -0
- package/dist/common/constants.js.map +1 -0
- package/dist/common/do-rpc-schema.d.ts +6 -6
- package/dist/common/do-rpc-schema.d.ts.map +1 -1
- package/dist/common/do-rpc-schema.js +4 -4
- package/dist/common/do-rpc-schema.js.map +1 -1
- package/dist/common/http-rpc-schema.d.ts +4 -4
- package/dist/common/http-rpc-schema.d.ts.map +1 -1
- package/dist/common/http-rpc-schema.js +4 -4
- package/dist/common/http-rpc-schema.js.map +1 -1
- package/dist/common/mod.d.ts +4 -1
- package/dist/common/mod.d.ts.map +1 -1
- package/dist/common/mod.js +4 -1
- package/dist/common/mod.js.map +1 -1
- package/dist/common/sync-message-types.d.ts +7 -7
- package/dist/common/sync-message-types.js +3 -3
- package/dist/common/sync-message-types.js.map +1 -1
- package/dist/common/ws-rpc-schema.d.ts +3 -3
- package/dist/common/ws-rpc-schema.d.ts.map +1 -1
- package/dist/common/ws-rpc-schema.js +3 -3
- package/dist/common/ws-rpc-schema.js.map +1 -1
- package/package.json +72 -14
- package/src/cf-worker/do/durable-object.ts +19 -10
- package/src/cf-worker/do/layer.ts +35 -13
- package/src/cf-worker/do/pull.ts +31 -14
- package/src/cf-worker/do/push.ts +49 -34
- package/src/cf-worker/do/sqlite.ts +14 -4
- package/src/cf-worker/do/sync-storage.ts +151 -31
- package/src/cf-worker/do/transport/do-rpc-server.ts +18 -7
- package/src/cf-worker/do/transport/http-rpc-server.ts +33 -13
- package/src/cf-worker/do/transport/ws-rpc-server.ts +40 -12
- package/src/cf-worker/shared.ts +136 -25
- package/src/cf-worker/worker.ts +107 -54
- package/src/client/transport/do-rpc-client.ts +41 -17
- package/src/client/transport/http-rpc-client.ts +43 -17
- package/src/client/transport/ws-rpc-client.ts +42 -19
- package/src/common/constants.ts +18 -0
- package/src/common/do-rpc-schema.ts +5 -4
- package/src/common/http-rpc-schema.ts +5 -4
- package/src/common/mod.ts +4 -2
- package/src/common/sync-message-types.ts +3 -3
- package/src/common/ws-rpc-schema.ts +4 -3
- package/dist/cf-worker/do/ws-chunking.d.ts +0 -22
- package/dist/cf-worker/do/ws-chunking.d.ts.map +0 -1
- package/dist/cf-worker/do/ws-chunking.js +0 -49
- package/dist/cf-worker/do/ws-chunking.js.map +0 -1
- package/src/cf-worker/do/ws-chunking.ts +0 -76
|
@@ -42,19 +42,20 @@ export declare const PullResponse: Schema.Struct<{
|
|
|
42
42
|
backendId: Schema.SchemaClass<string, string, never>;
|
|
43
43
|
}>;
|
|
44
44
|
export declare const emptyPullResponse: (backendId: string) => {
|
|
45
|
+
readonly backendId: string;
|
|
45
46
|
readonly batch: readonly {
|
|
47
|
+
readonly metadata: import("effect/Option").Option<{
|
|
48
|
+
readonly createdAt: string;
|
|
49
|
+
readonly _tag: "SyncMessage.SyncMetadata";
|
|
50
|
+
}>;
|
|
46
51
|
readonly eventEncoded: {
|
|
47
52
|
readonly name: string;
|
|
48
53
|
readonly args: any;
|
|
49
|
-
readonly seqNum:
|
|
50
|
-
readonly parentSeqNum:
|
|
54
|
+
readonly seqNum: number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">;
|
|
55
|
+
readonly parentSeqNum: number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">;
|
|
51
56
|
readonly clientId: string;
|
|
52
57
|
readonly sessionId: string;
|
|
53
58
|
};
|
|
54
|
-
readonly metadata: import("effect/Option").Option<{
|
|
55
|
-
readonly _tag: "SyncMessage.SyncMetadata";
|
|
56
|
-
readonly createdAt: string;
|
|
57
|
-
}>;
|
|
58
59
|
}[];
|
|
59
60
|
readonly pageInfo: {
|
|
60
61
|
readonly _tag: "MoreUnknown";
|
|
@@ -64,7 +65,6 @@ export declare const emptyPullResponse: (backendId: string) => {
|
|
|
64
65
|
} | {
|
|
65
66
|
readonly _tag: "NoMore";
|
|
66
67
|
};
|
|
67
|
-
readonly backendId: string;
|
|
68
68
|
};
|
|
69
69
|
export type PullResponse = typeof PullResponse.Type;
|
|
70
70
|
export declare const PushRequest: Schema.Struct<{
|
|
@@ -14,12 +14,12 @@ export const PullRequest = Schema.Struct({
|
|
|
14
14
|
/** Omitting the cursor will start from the beginning */
|
|
15
15
|
cursor: Schema.Option(Schema.Struct({
|
|
16
16
|
backendId: BackendId,
|
|
17
|
-
eventSequenceNumber: EventSequenceNumber.
|
|
17
|
+
eventSequenceNumber: EventSequenceNumber.Global.Schema,
|
|
18
18
|
})),
|
|
19
19
|
}).annotations({ title: '@livestore/sync-cf:PullRequest' });
|
|
20
20
|
export const PullResponse = Schema.Struct({
|
|
21
21
|
batch: Schema.Array(Schema.Struct({
|
|
22
|
-
eventEncoded: LiveStoreEvent.
|
|
22
|
+
eventEncoded: LiveStoreEvent.Global.Encoded,
|
|
23
23
|
metadata: Schema.Option(SyncMetadata),
|
|
24
24
|
})),
|
|
25
25
|
pageInfo: SyncBackend.PullResPageInfo,
|
|
@@ -31,7 +31,7 @@ export const emptyPullResponse = (backendId) => PullResponse.make({
|
|
|
31
31
|
backendId,
|
|
32
32
|
});
|
|
33
33
|
export const PushRequest = Schema.Struct({
|
|
34
|
-
batch: Schema.Array(LiveStoreEvent.
|
|
34
|
+
batch: Schema.Array(LiveStoreEvent.Global.Encoded),
|
|
35
35
|
backendId: Schema.Option(BackendId),
|
|
36
36
|
}).annotations({ title: '@livestore/sync-cf:PushRequest' });
|
|
37
37
|
export const PushAck = Schema.Struct({}).annotations({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-message-types.js","sourceRoot":"","sources":["../../src/common/sync-message-types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEhD;;;;GAIG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC,0BAA0B,EAAE;IAC1E,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC,MAAM;CACzB,CAAC,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAC,CAAA;AAI5D,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;IACvC,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC,MAAM,CACnB,MAAM,CAAC,MAAM,CAAC;QACZ,SAAS,EAAE,SAAS;QACpB,mBAAmB,EAAE,mBAAmB,CAAC,
|
|
1
|
+
{"version":3,"file":"sync-message-types.js","sourceRoot":"","sources":["../../src/common/sync-message-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BackendIdMismatchError, ServerAheadError, UnknownError } from '@livestore/common';
|
|
2
2
|
import { Rpc, RpcGroup, Schema } from '@livestore/utils/effect';
|
|
3
3
|
declare const SyncWsRpc_base: RpcGroup.RpcGroup<Rpc.Rpc<"SyncWsRpc.Pull", Schema.Struct<{
|
|
4
4
|
cursor: Schema.Option<Schema.Struct<{
|
|
@@ -29,7 +29,7 @@ declare const SyncWsRpc_base: RpcGroup.RpcGroup<Rpc.Rpc<"SyncWsRpc.Pull", Schema
|
|
|
29
29
|
remaining: typeof Schema.Number;
|
|
30
30
|
}>, Schema.TaggedStruct<"NoMore", {}>]>;
|
|
31
31
|
backendId: Schema.SchemaClass<string, string, never>;
|
|
32
|
-
}>, typeof
|
|
32
|
+
}>, Schema.Union<[typeof UnknownError, typeof BackendIdMismatchError]>>, typeof Schema.Never, never> | Rpc.Rpc<"SyncWsRpc.Push", Schema.Struct<{
|
|
33
33
|
batch: Schema.Array$<Schema.Struct<{
|
|
34
34
|
name: typeof Schema.String;
|
|
35
35
|
args: typeof Schema.Any;
|
|
@@ -41,7 +41,7 @@ declare const SyncWsRpc_base: RpcGroup.RpcGroup<Rpc.Rpc<"SyncWsRpc.Pull", Schema
|
|
|
41
41
|
backendId: Schema.Option<Schema.SchemaClass<string, string, never>>;
|
|
42
42
|
storeId: typeof Schema.String;
|
|
43
43
|
payload: Schema.optional<Schema.Schema<Schema.JsonValue, Schema.JsonValue, never>>;
|
|
44
|
-
}>, Schema.Struct<{}>, typeof
|
|
44
|
+
}>, Schema.Struct<{}>, Schema.Union<[typeof UnknownError, typeof ServerAheadError, typeof BackendIdMismatchError]>, never>>;
|
|
45
45
|
/**
|
|
46
46
|
* WebSocket RPC Schema for LiveStore CF Sync Provider
|
|
47
47
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ws-rpc-schema.d.ts","sourceRoot":"","sources":["../../src/common/ws-rpc-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"ws-rpc-schema.d.ts","sourceRoot":"","sources":["../../src/common/ws-rpc-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAC1F,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;;;;;;;;IAgBzD,qEAAqE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAZ3E;;;;;;GAMG;AACH,qBAAa,SAAU,SAAQ,cAwB9B;CAAG"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BackendIdMismatchError, ServerAheadError, UnknownError } from '@livestore/common';
|
|
2
2
|
import { Rpc, RpcGroup, Schema } from '@livestore/utils/effect';
|
|
3
3
|
import * as SyncMessage from "./sync-message-types.js";
|
|
4
4
|
/**
|
|
@@ -17,7 +17,7 @@ export class SyncWsRpc extends RpcGroup.make(Rpc.make('SyncWsRpc.Pull', {
|
|
|
17
17
|
...SyncMessage.PullRequest.fields,
|
|
18
18
|
}),
|
|
19
19
|
success: SyncMessage.PullResponse,
|
|
20
|
-
error:
|
|
20
|
+
error: Schema.Union(UnknownError, BackendIdMismatchError),
|
|
21
21
|
stream: true,
|
|
22
22
|
}), Rpc.make('SyncWsRpc.Push', {
|
|
23
23
|
payload: Schema.Struct({
|
|
@@ -26,7 +26,7 @@ export class SyncWsRpc extends RpcGroup.make(Rpc.make('SyncWsRpc.Pull', {
|
|
|
26
26
|
...SyncMessage.PushRequest.fields,
|
|
27
27
|
}),
|
|
28
28
|
success: SyncMessage.PushAck,
|
|
29
|
-
error:
|
|
29
|
+
error: Schema.Union(UnknownError, ServerAheadError, BackendIdMismatchError),
|
|
30
30
|
})) {
|
|
31
31
|
}
|
|
32
32
|
//# sourceMappingURL=ws-rpc-schema.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ws-rpc-schema.js","sourceRoot":"","sources":["../../src/common/ws-rpc-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"ws-rpc-schema.js","sourceRoot":"","sources":["../../src/common/ws-rpc-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAC1F,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAE/D,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAA;AAEtD;;;;;;GAMG;AACH,MAAM,OAAO,SAAU,SAAQ,QAAQ,CAAC,IAAI,CAC1C,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE;IACzB,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC,MAAM;QACtB,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC;QAC1C,qEAAqE;QACrE,IAAI,EAAE,MAAM,CAAC,OAAO;QACpB,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM;KAClC,CAAC;IACF,OAAO,EAAE,WAAW,CAAC,YAAY;IACjC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,YAAY,EAAE,sBAAsB,CAAC;IACzD,MAAM,EAAE,IAAI;CACb,CAAC,EACF,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE;IACzB,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC,MAAM;QACtB,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC;QAC1C,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM;KAClC,CAAC;IACF,OAAO,EAAE,WAAW,CAAC,OAAO;IAC5B,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,YAAY,EAAE,gBAAgB,EAAE,sBAAsB,CAAC;CAC5E,CAAC,CAGH;CAAG"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livestore/sync-cf",
|
|
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
|
+
"README.md"
|
|
14
|
+
],
|
|
4
15
|
"type": "module",
|
|
5
16
|
"sideEffects": false,
|
|
6
17
|
"exports": {
|
|
@@ -8,22 +19,69 @@
|
|
|
8
19
|
"./common": "./dist/common/mod.js",
|
|
9
20
|
"./cf-worker": "./dist/cf-worker/mod.js"
|
|
10
21
|
},
|
|
11
|
-
"dependencies": {
|
|
12
|
-
"@cloudflare/workers-types": "4.20250923.0",
|
|
13
|
-
"@livestore/common": "0.4.0-dev.9",
|
|
14
|
-
"@livestore/common-cf": "0.4.0-dev.9",
|
|
15
|
-
"@livestore/utils": "0.4.0-dev.9"
|
|
16
|
-
},
|
|
17
|
-
"files": [
|
|
18
|
-
"dist",
|
|
19
|
-
"src",
|
|
20
|
-
"package.json",
|
|
21
|
-
"README.md"
|
|
22
|
-
],
|
|
23
|
-
"license": "Apache-2.0",
|
|
24
22
|
"publishConfig": {
|
|
25
23
|
"access": "public"
|
|
26
24
|
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@cloudflare/workers-types": "4.20251118.0",
|
|
27
|
+
"@livestore/common": "^0.4.0",
|
|
28
|
+
"@livestore/common-cf": "^0.4.0",
|
|
29
|
+
"@livestore/utils": "^0.4.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@effect/ai": "0.35.0",
|
|
33
|
+
"@effect/cli": "0.75.1",
|
|
34
|
+
"@effect/cluster": "0.58.2",
|
|
35
|
+
"@effect/experimental": "0.60.0",
|
|
36
|
+
"@effect/opentelemetry": "0.63.0",
|
|
37
|
+
"@effect/platform": "0.96.1",
|
|
38
|
+
"@effect/platform-browser": "0.76.0",
|
|
39
|
+
"@effect/platform-bun": "0.89.0",
|
|
40
|
+
"@effect/platform-node": "0.106.0",
|
|
41
|
+
"@effect/printer": "0.49.0",
|
|
42
|
+
"@effect/printer-ansi": "0.49.0",
|
|
43
|
+
"@effect/rpc": "0.75.1",
|
|
44
|
+
"@effect/sql": "0.51.1",
|
|
45
|
+
"@effect/typeclass": "0.40.0",
|
|
46
|
+
"@effect/vitest": "0.29.0",
|
|
47
|
+
"@opentelemetry/api": "1.9.0",
|
|
48
|
+
"@opentelemetry/resources": "2.2.0",
|
|
49
|
+
"@standard-schema/spec": "1.1.0",
|
|
50
|
+
"effect": "3.21.2"
|
|
51
|
+
},
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"@effect/ai": "^0.35.0",
|
|
54
|
+
"@effect/cli": "^0.75.1",
|
|
55
|
+
"@effect/cluster": "^0.58.2",
|
|
56
|
+
"@effect/experimental": "^0.60.0",
|
|
57
|
+
"@effect/opentelemetry": "^0.63.0",
|
|
58
|
+
"@effect/platform": "^0.96.1",
|
|
59
|
+
"@effect/platform-browser": "^0.76.0",
|
|
60
|
+
"@effect/platform-bun": "^0.89.0",
|
|
61
|
+
"@effect/platform-node": "^0.106.0",
|
|
62
|
+
"@effect/printer": "^0.49.0",
|
|
63
|
+
"@effect/printer-ansi": "^0.49.0",
|
|
64
|
+
"@effect/rpc": "^0.75.1",
|
|
65
|
+
"@effect/sql": "^0.51.1",
|
|
66
|
+
"@effect/typeclass": "^0.40.0",
|
|
67
|
+
"@effect/vitest": "^0.29.0",
|
|
68
|
+
"@opentelemetry/api": "^1.9.0",
|
|
69
|
+
"@opentelemetry/resources": "^2.2.0",
|
|
70
|
+
"@standard-schema/spec": "^1.1.0",
|
|
71
|
+
"effect": "^3.21.2"
|
|
72
|
+
},
|
|
73
|
+
"$genie": {
|
|
74
|
+
"source": "package.json.genie.ts",
|
|
75
|
+
"warning": "DO NOT EDIT - changes will be overwritten",
|
|
76
|
+
"workspaceClosureDirs": [
|
|
77
|
+
"packages/@livestore/common",
|
|
78
|
+
"packages/@livestore/common-cf",
|
|
79
|
+
"packages/@livestore/sync-cf",
|
|
80
|
+
"packages/@livestore/utils",
|
|
81
|
+
"packages/@livestore/utils-dev",
|
|
82
|
+
"packages/@livestore/webmesh"
|
|
83
|
+
]
|
|
84
|
+
},
|
|
27
85
|
"scripts": {
|
|
28
86
|
"test": "echo 'No tests yet'"
|
|
29
87
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
2
|
|
|
3
3
|
import { DurableObject } from 'cloudflare:workers'
|
|
4
|
+
|
|
4
5
|
import { type CfTypes, setupDurableObjectWebSocketRpc } from '@livestore/common-cf'
|
|
5
6
|
import { CfDeclare } from '@livestore/common-cf/declare'
|
|
6
7
|
import {
|
|
@@ -14,8 +15,10 @@ import {
|
|
|
14
15
|
Schema,
|
|
15
16
|
type Scope,
|
|
16
17
|
} from '@livestore/utils/effect'
|
|
18
|
+
|
|
17
19
|
import {
|
|
18
20
|
type Env,
|
|
21
|
+
extractForwardedHeaders,
|
|
19
22
|
type MakeDurableObjectClassOptions,
|
|
20
23
|
matchSyncRequest,
|
|
21
24
|
type SyncBackendRpcInterface,
|
|
@@ -33,7 +36,7 @@ declare class Response extends CfDeclare.Response {}
|
|
|
33
36
|
declare class WebSocketPair extends CfDeclare.WebSocketPair {}
|
|
34
37
|
declare class WebSocketRequestResponsePair extends CfDeclare.WebSocketRequestResponsePair {}
|
|
35
38
|
|
|
36
|
-
const DurableObjectBase = DurableObject
|
|
39
|
+
const DurableObjectBase = DurableObject as any as new (
|
|
37
40
|
state: CfTypes.DurableObjectState,
|
|
38
41
|
env: Env,
|
|
39
42
|
) => CfTypes.DurableObject & { ctx: CfTypes.DurableObjectState; env: Env }
|
|
@@ -48,7 +51,7 @@ export type MakeDurableObjectClass = (options?: MakeDurableObjectClassOptions) =
|
|
|
48
51
|
|
|
49
52
|
/**
|
|
50
53
|
* Creates a Durable Object class for handling WebSocket-based sync.
|
|
51
|
-
* A sync
|
|
54
|
+
* A sync Durable Object is uniquely scoped to a specific `storeId`.
|
|
52
55
|
*
|
|
53
56
|
* The sync DO supports 3 transport modes:
|
|
54
57
|
* - HTTP JSON-RPC
|
|
@@ -87,14 +90,14 @@ export const makeDurableObject: MakeDurableObjectClass = (options) => {
|
|
|
87
90
|
|
|
88
91
|
const Logging = Logger.consoleWithThread('SyncDo')
|
|
89
92
|
|
|
90
|
-
const Observability = options?.otel?.baseUrl
|
|
91
|
-
? Otlp.layer({
|
|
93
|
+
const Observability: Layer.Layer<never> = options?.otel?.baseUrl !== undefined
|
|
94
|
+
? (Otlp.layer({
|
|
92
95
|
baseUrl: options.otel.baseUrl,
|
|
93
96
|
tracerExportInterval: 50,
|
|
94
97
|
resource: {
|
|
95
98
|
serviceName: options.otel.serviceName ?? 'sync-cf-do',
|
|
96
99
|
},
|
|
97
|
-
}).pipe(Layer.provide(FetchHttpClient.layer))
|
|
100
|
+
}).pipe(Layer.provide(FetchHttpClient.layer)) as Layer.Layer<never>)
|
|
98
101
|
: Layer.empty
|
|
99
102
|
|
|
100
103
|
return class SyncBackendDOBase extends DurableObjectBase implements SyncBackendRpcInterface {
|
|
@@ -106,7 +109,7 @@ export const makeDurableObject: MakeDurableObjectClass = (options) => {
|
|
|
106
109
|
const WebSocketRpcServerLive = makeRpcServer({ doSelf: this, doOptions: options })
|
|
107
110
|
|
|
108
111
|
// This registers the `webSocketMessage` and `webSocketClose` handlers
|
|
109
|
-
if (enabledTransports.has('ws')) {
|
|
112
|
+
if (enabledTransports.has('ws') === true) {
|
|
110
113
|
setupDurableObjectWebSocketRpc({
|
|
111
114
|
doSelf: this,
|
|
112
115
|
rpcLayer: WebSocketRpcServerLive,
|
|
@@ -142,7 +145,7 @@ export const makeDurableObject: MakeDurableObjectClass = (options) => {
|
|
|
142
145
|
}
|
|
143
146
|
}
|
|
144
147
|
|
|
145
|
-
fetch = async (request: Request): Promise<Response> =>
|
|
148
|
+
override fetch = async (request: Request): Promise<Response> =>
|
|
146
149
|
Effect.gen(this, function* () {
|
|
147
150
|
const searchParams = matchSyncRequest(request)
|
|
148
151
|
if (searchParams === undefined) {
|
|
@@ -155,16 +158,20 @@ export const makeDurableObject: MakeDurableObjectClass = (options) => {
|
|
|
155
158
|
throw new Error(`Transport ${transport} is not enabled (based on \`options.enabledTransports\`)`)
|
|
156
159
|
}
|
|
157
160
|
|
|
161
|
+
// Extract headers to forward based on configuration (available for all transports)
|
|
162
|
+
const headers = extractForwardedHeaders(request, options?.forwardHeaders)
|
|
163
|
+
|
|
158
164
|
if (transport === 'http') {
|
|
159
|
-
return yield* this.handleHttp(request)
|
|
165
|
+
return yield* this.handleHttp(request, headers)
|
|
160
166
|
}
|
|
161
167
|
|
|
162
168
|
if (transport === 'ws') {
|
|
163
169
|
const { 0: client, 1: server } = new WebSocketPair()
|
|
164
170
|
|
|
165
171
|
// Since we're using websocket hibernation, we need to remember the storeId for subsequent `webSocketMessage` calls
|
|
172
|
+
// Also store forwarded headers so they're available after hibernation resume
|
|
166
173
|
server.serializeAttachment(
|
|
167
|
-
Schema.encodeSync(WebSocketAttachmentSchema)({ storeId, payload, pullRequestIds: [] }),
|
|
174
|
+
Schema.encodeSync(WebSocketAttachmentSchema)({ storeId, payload, pullRequestIds: [], headers }),
|
|
168
175
|
)
|
|
169
176
|
|
|
170
177
|
// See https://developers.cloudflare.com/durable-objects/examples/websocket-hibernation-server
|
|
@@ -220,9 +227,11 @@ export const makeDurableObject: MakeDurableObjectClass = (options) => {
|
|
|
220
227
|
*
|
|
221
228
|
* Requires the `enable_request_signal` compatibility flag to properly support `pull` streaming responses
|
|
222
229
|
*/
|
|
223
|
-
private handleHttp = (request: CfTypes.Request) =>
|
|
230
|
+
private handleHttp = (request: CfTypes.Request, forwardedHeaders: Record<string, string> | undefined) =>
|
|
224
231
|
createHttpRpcHandler({
|
|
225
232
|
request,
|
|
233
|
+
...(options?.http?.responseHeaders !== undefined ? { responseHeaders: options.http.responseHeaders } : {}),
|
|
234
|
+
...(forwardedHeaders !== undefined ? { forwardedHeaders } : {}),
|
|
226
235
|
}).pipe(Effect.withSpan('@livestore/sync-cf:durable-object:handleHttp'))
|
|
227
236
|
|
|
228
237
|
private runEffectAsPromise = <T, E = never>(effect: Effect.Effect<T, E, Scope.Scope>): Promise<T> =>
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { EventSequenceNumber, State } from '@livestore/common/schema'
|
|
1
|
+
import { UnknownError } from '@livestore/common'
|
|
3
2
|
import type { CfTypes } from '@livestore/common-cf'
|
|
3
|
+
import { EventSequenceNumber, State } from '@livestore/common/schema'
|
|
4
4
|
import { shouldNeverHappen } from '@livestore/utils'
|
|
5
5
|
import { Effect, Predicate } from '@livestore/utils/effect'
|
|
6
6
|
import { nanoid } from '@livestore/utils/nanoid'
|
|
7
|
+
|
|
7
8
|
import type { Env, MakeDurableObjectClassOptions, RpcSubscription } from '../shared.ts'
|
|
8
9
|
import { contextTable, eventlogTable } from './sqlite.ts'
|
|
9
10
|
import { makeStorage } from './sync-storage.ts'
|
|
@@ -27,7 +28,7 @@ export class DoCtx extends Effect.Service<DoCtx>()('DoCtx', {
|
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
const getStoreId = (from: CfTypes.Request | { storeId: string }) => {
|
|
30
|
-
if (Predicate.hasProperty(from, 'url')) {
|
|
31
|
+
if (Predicate.hasProperty(from, 'url') === true) {
|
|
31
32
|
const url = new URL(from.url)
|
|
32
33
|
return (
|
|
33
34
|
url.searchParams.get('storeId') ?? shouldNeverHappen(`No storeId provided in request URL search params`)
|
|
@@ -37,15 +38,36 @@ export class DoCtx extends Effect.Service<DoCtx>()('DoCtx', {
|
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
const storeId = getStoreId(from)
|
|
40
|
-
|
|
41
|
+
// Resolve storage engine
|
|
42
|
+
const makeEngine = Effect.gen(function* () {
|
|
43
|
+
const opt = doOptions?.storage
|
|
44
|
+
if (opt?._tag === 'd1') {
|
|
45
|
+
const db = (doSelf.env as any)[opt.binding]
|
|
46
|
+
if (db == null) {
|
|
47
|
+
return yield* UnknownError.make({ cause: new Error(`D1 binding '${opt.binding}' not found on env`) })
|
|
48
|
+
}
|
|
49
|
+
return { _tag: 'd1' as const, db }
|
|
50
|
+
} else if (opt?._tag === 'do-sqlite' || opt === undefined) {
|
|
51
|
+
return { _tag: 'do-sqlite' as const }
|
|
52
|
+
} else return shouldNeverHappen(`Invalid storage engine`, opt)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
const engine = yield* makeEngine
|
|
56
|
+
|
|
57
|
+
const storage = makeStorage(doSelf.ctx, storeId, engine)
|
|
41
58
|
|
|
42
59
|
// Initialize database tables
|
|
43
60
|
{
|
|
44
61
|
const colSpec = State.SQLite.makeColumnSpec(eventlogTable.sqliteDef.ast)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
62
|
+
if (engine._tag === 'd1') {
|
|
63
|
+
// D1 database is async, so we need to use a promise
|
|
64
|
+
yield* Effect.promise(() =>
|
|
65
|
+
engine.db.exec(`CREATE TABLE IF NOT EXISTS "${storage.dbName}" (${colSpec}) strict`),
|
|
66
|
+
)
|
|
67
|
+
} else {
|
|
68
|
+
// DO SQLite table lives in Durable Object storage
|
|
69
|
+
doSelf.ctx.storage.sql.exec(`CREATE TABLE IF NOT EXISTS "${storage.dbName}" (${colSpec}) strict`)
|
|
70
|
+
}
|
|
49
71
|
}
|
|
50
72
|
{
|
|
51
73
|
const colSpec = State.SQLite.makeColumnSpec(contextTable.sqliteDef.ast)
|
|
@@ -56,14 +78,14 @@ export class DoCtx extends Effect.Service<DoCtx>()('DoCtx', {
|
|
|
56
78
|
.exec(`SELECT * FROM "${contextTable.sqliteDef.name}" WHERE storeId = ?`, storeId)
|
|
57
79
|
.toArray()[0] as typeof contextTable.rowSchema.Type | undefined
|
|
58
80
|
|
|
59
|
-
const currentHeadRef = { current: storageRow?.currentHead ?? EventSequenceNumber.ROOT.global }
|
|
81
|
+
const currentHeadRef = { current: storageRow?.currentHead ?? EventSequenceNumber.Client.ROOT.global }
|
|
60
82
|
|
|
61
83
|
// TODO do concistency check with eventlog table to make sure the head is consistent
|
|
62
84
|
|
|
63
|
-
// Should be the same backendId for lifetime of the
|
|
85
|
+
// Should be the same backendId for lifetime of the Durable Object
|
|
64
86
|
const backendId = storageRow?.backendId ?? nanoid()
|
|
65
87
|
|
|
66
|
-
const updateCurrentHead = (currentHead: EventSequenceNumber.
|
|
88
|
+
const updateCurrentHead = (currentHead: EventSequenceNumber.Global.Type) => {
|
|
67
89
|
doSelf.ctx.storage.sql.exec(
|
|
68
90
|
`INSERT OR REPLACE INTO "${contextTable.sqliteDef.name}" (storeId, currentHead, backendId) VALUES (?, ?, ?)`,
|
|
69
91
|
storeId,
|
|
@@ -96,12 +118,12 @@ export class DoCtx extends Effect.Service<DoCtx>()('DoCtx', {
|
|
|
96
118
|
|
|
97
119
|
// Set initial current head to root
|
|
98
120
|
if (storageRow === undefined) {
|
|
99
|
-
updateCurrentHead(EventSequenceNumber.ROOT.global)
|
|
121
|
+
updateCurrentHead(EventSequenceNumber.Client.ROOT.global)
|
|
100
122
|
}
|
|
101
123
|
|
|
102
124
|
return storageCache
|
|
103
125
|
},
|
|
104
|
-
|
|
126
|
+
UnknownError.mapToUnknownError,
|
|
105
127
|
Effect.withSpan('@livestore/sync-cf:durable-object:makeDoCtx'),
|
|
106
128
|
),
|
|
107
129
|
}) {}
|
package/src/cf-worker/do/pull.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { BackendIdMismatchError,
|
|
1
|
+
import { BackendIdMismatchError, SyncBackend, UnknownError } from '@livestore/common'
|
|
2
|
+
import { splitChunkBySize } from '@livestore/common/sync'
|
|
2
3
|
import { Chunk, Effect, Option, Schema, Stream } from '@livestore/utils/effect'
|
|
4
|
+
|
|
5
|
+
import { MAX_PULL_EVENTS_PER_MESSAGE, MAX_WS_MESSAGE_BYTES } from '../../common/constants.ts'
|
|
3
6
|
import { SyncMessage } from '../../common/mod.ts'
|
|
4
|
-
import {
|
|
7
|
+
import type { ForwardedHeaders } from '../shared.ts'
|
|
5
8
|
import { DoCtx } from './layer.ts'
|
|
6
|
-
import { splitChunkBySize } from './ws-chunking.ts'
|
|
7
9
|
|
|
8
10
|
const encodePullResponse = Schema.encodeSync(SyncMessage.PullResponse)
|
|
9
11
|
|
|
@@ -16,16 +18,27 @@ const encodePullResponse = Schema.encodeSync(SyncMessage.PullResponse)
|
|
|
16
18
|
// DO RPC:
|
|
17
19
|
// - Further chunks will be emitted manually in `push.ts`
|
|
18
20
|
// - If the client sends a `Interrupt` RPC message, TODO
|
|
19
|
-
export const makeEndingPullStream = (
|
|
20
|
-
req
|
|
21
|
-
payload
|
|
22
|
-
|
|
21
|
+
export const makeEndingPullStream = ({
|
|
22
|
+
req,
|
|
23
|
+
payload,
|
|
24
|
+
headers,
|
|
25
|
+
}: {
|
|
26
|
+
req: SyncMessage.PullRequest
|
|
27
|
+
payload: Schema.JsonValue | undefined
|
|
28
|
+
headers: ForwardedHeaders | undefined
|
|
29
|
+
}): Stream.Stream<SyncMessage.PullResponse, UnknownError | BackendIdMismatchError, DoCtx> =>
|
|
23
30
|
Effect.gen(function* () {
|
|
24
31
|
const { doOptions, backendId, storeId, storage } = yield* DoCtx
|
|
25
32
|
|
|
26
|
-
if (doOptions?.onPull) {
|
|
27
|
-
yield* Effect.tryAll(() =>
|
|
28
|
-
|
|
33
|
+
if (doOptions?.onPull !== undefined) {
|
|
34
|
+
yield* Effect.tryAll(() =>
|
|
35
|
+
doOptions.onPull!(req, {
|
|
36
|
+
storeId,
|
|
37
|
+
...(payload !== undefined ? { payload } : {}),
|
|
38
|
+
...(headers !== undefined ? { headers } : {}),
|
|
39
|
+
}),
|
|
40
|
+
).pipe(
|
|
41
|
+
UnknownError.mapToUnknownError,
|
|
29
42
|
)
|
|
30
43
|
}
|
|
31
44
|
|
|
@@ -38,7 +51,7 @@ export const makeEndingPullStream = (
|
|
|
38
51
|
)
|
|
39
52
|
|
|
40
53
|
return storedEvents.pipe(
|
|
41
|
-
Stream.
|
|
54
|
+
Stream.mapChunksEffect(
|
|
42
55
|
splitChunkBySize({
|
|
43
56
|
maxItems: MAX_PULL_EVENTS_PER_MESSAGE,
|
|
44
57
|
maxBytes: MAX_WS_MESSAGE_BYTES,
|
|
@@ -63,8 +76,8 @@ export const makeEndingPullStream = (
|
|
|
63
76
|
}),
|
|
64
77
|
Stream.tap(
|
|
65
78
|
Effect.fn(function* (res) {
|
|
66
|
-
if (doOptions?.onPullRes) {
|
|
67
|
-
yield* Effect.tryAll(() => doOptions.onPullRes!(res)).pipe(
|
|
79
|
+
if (doOptions?.onPullRes !== undefined) {
|
|
80
|
+
yield* Effect.tryAll(() => doOptions.onPullRes!(res)).pipe(UnknownError.mapToUnknownError)
|
|
68
81
|
}
|
|
69
82
|
}),
|
|
70
83
|
),
|
|
@@ -72,6 +85,10 @@ export const makeEndingPullStream = (
|
|
|
72
85
|
)
|
|
73
86
|
}).pipe(
|
|
74
87
|
Stream.unwrap,
|
|
75
|
-
Stream.mapError((cause) =>
|
|
88
|
+
Stream.mapError((cause) =>
|
|
89
|
+
cause._tag === 'BackendIdMismatchError' || cause._tag === 'UnknownError'
|
|
90
|
+
? cause
|
|
91
|
+
: new UnknownError({ cause }),
|
|
92
|
+
),
|
|
76
93
|
Stream.withSpan('cloudflare-provider:pull'),
|
|
77
94
|
)
|