@livestore/sync-cf 0.4.0 → 0.5.0-dev.1
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 +5 -5
- package/dist/.tsbuildinfo +1 -1
- package/dist/cf-worker/do/durable-object.d.ts.map +1 -1
- package/dist/cf-worker/do/durable-object.js +53 -36
- package/dist/cf-worker/do/durable-object.js.map +1 -1
- package/dist/cf-worker/do/layer.d.ts +22 -18
- package/dist/cf-worker/do/layer.d.ts.map +1 -1
- package/dist/cf-worker/do/layer.js +45 -35
- package/dist/cf-worker/do/layer.js.map +1 -1
- package/dist/cf-worker/do/observability.d.ts +23 -0
- package/dist/cf-worker/do/observability.d.ts.map +1 -0
- package/dist/cf-worker/do/observability.js +52 -0
- package/dist/cf-worker/do/observability.js.map +1 -0
- package/dist/cf-worker/do/observability.test.d.ts +2 -0
- package/dist/cf-worker/do/observability.test.d.ts.map +1 -0
- package/dist/cf-worker/do/observability.test.js +204 -0
- package/dist/cf-worker/do/observability.test.js.map +1 -0
- package/dist/cf-worker/do/pull.d.ts +3 -3
- package/dist/cf-worker/do/pull.d.ts.map +1 -1
- package/dist/cf-worker/do/pull.js +19 -20
- package/dist/cf-worker/do/pull.js.map +1 -1
- package/dist/cf-worker/do/push.d.ts +16 -3
- package/dist/cf-worker/do/push.d.ts.map +1 -1
- package/dist/cf-worker/do/push.js +74 -53
- package/dist/cf-worker/do/push.js.map +1 -1
- package/dist/cf-worker/do/push.test.d.ts +2 -0
- package/dist/cf-worker/do/push.test.d.ts.map +1 -0
- package/dist/cf-worker/do/push.test.js +30 -0
- package/dist/cf-worker/do/push.test.js.map +1 -0
- package/dist/cf-worker/do/sqlite.d.ts +34 -46
- package/dist/cf-worker/do/sqlite.d.ts.map +1 -1
- package/dist/cf-worker/do/sqlite.js +2 -2
- package/dist/cf-worker/do/sqlite.js.map +1 -1
- package/dist/cf-worker/do/sync-storage.d.ts +7 -6
- package/dist/cf-worker/do/sync-storage.d.ts.map +1 -1
- package/dist/cf-worker/do/sync-storage.js +29 -17
- package/dist/cf-worker/do/sync-storage.js.map +1 -1
- package/dist/cf-worker/do/transport/do-rpc-server.d.ts +17 -2
- package/dist/cf-worker/do/transport/do-rpc-server.d.ts.map +1 -1
- package/dist/cf-worker/do/transport/do-rpc-server.js +41 -23
- package/dist/cf-worker/do/transport/do-rpc-server.js.map +1 -1
- package/dist/cf-worker/do/transport/do-rpc-server.test.d.ts +2 -0
- package/dist/cf-worker/do/transport/do-rpc-server.test.d.ts.map +1 -0
- package/dist/cf-worker/do/transport/do-rpc-server.test.js +28 -0
- package/dist/cf-worker/do/transport/do-rpc-server.test.js.map +1 -0
- package/dist/cf-worker/do/transport/http-rpc-server.d.ts +2 -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 +12 -12
- package/dist/cf-worker/do/transport/http-rpc-server.js.map +1 -1
- package/dist/cf-worker/do/transport/ws-rpc-server.d.ts +9 -2
- package/dist/cf-worker/do/transport/ws-rpc-server.d.ts.map +1 -1
- package/dist/cf-worker/do/transport/ws-rpc-server.js +37 -29
- package/dist/cf-worker/do/transport/ws-rpc-server.js.map +1 -1
- package/dist/cf-worker/mod.js +3 -3
- package/dist/cf-worker/shared.d.ts +37 -29
- package/dist/cf-worker/shared.d.ts.map +1 -1
- package/dist/cf-worker/shared.js +14 -12
- package/dist/cf-worker/shared.js.map +1 -1
- package/dist/cf-worker/worker.d.ts +9 -9
- package/dist/cf-worker/worker.d.ts.map +1 -1
- package/dist/cf-worker/worker.js +17 -15
- package/dist/cf-worker/worker.js.map +1 -1
- package/dist/client/mod.js +3 -3
- package/dist/client/transport/do-rpc-client.d.ts +18 -6
- package/dist/client/transport/do-rpc-client.d.ts.map +1 -1
- package/dist/client/transport/do-rpc-client.js +112 -38
- package/dist/client/transport/do-rpc-client.js.map +1 -1
- package/dist/client/transport/do-rpc-client.test.d.ts +2 -0
- package/dist/client/transport/do-rpc-client.test.d.ts.map +1 -0
- package/dist/client/transport/do-rpc-client.test.js +268 -0
- package/dist/client/transport/do-rpc-client.test.js.map +1 -0
- package/dist/client/transport/http-rpc-client.d.ts +3 -3
- package/dist/client/transport/http-rpc-client.d.ts.map +1 -1
- package/dist/client/transport/http-rpc-client.js +48 -29
- package/dist/client/transport/http-rpc-client.js.map +1 -1
- package/dist/client/transport/rpc-client-error.d.ts +5 -0
- package/dist/client/transport/rpc-client-error.d.ts.map +1 -0
- package/dist/client/transport/rpc-client-error.js +8 -0
- package/dist/client/transport/rpc-client-error.js.map +1 -0
- package/dist/client/transport/rpc-client-error.test.d.ts +2 -0
- package/dist/client/transport/rpc-client-error.test.d.ts.map +1 -0
- package/dist/client/transport/rpc-client-error.test.js +33 -0
- package/dist/client/transport/rpc-client-error.test.js.map +1 -0
- package/dist/client/transport/ws-rpc-client.d.ts +3 -3
- package/dist/client/transport/ws-rpc-client.d.ts.map +1 -1
- package/dist/client/transport/ws-rpc-client.js +33 -23
- package/dist/client/transport/ws-rpc-client.js.map +1 -1
- package/dist/common/do-rpc-schema.d.ts +53 -41
- package/dist/common/do-rpc-schema.d.ts.map +1 -1
- package/dist/common/do-rpc-schema.js +13 -4
- package/dist/common/do-rpc-schema.js.map +1 -1
- package/dist/common/http-rpc-schema.d.ts +38 -39
- package/dist/common/http-rpc-schema.d.ts.map +1 -1
- package/dist/common/http-rpc-schema.js +6 -6
- package/dist/common/http-rpc-schema.js.map +1 -1
- package/dist/common/mod.d.ts +5 -5
- package/dist/common/mod.d.ts.map +1 -1
- package/dist/common/mod.js +7 -7
- package/dist/common/mod.js.map +1 -1
- package/dist/common/sync-message-types.d.ts +116 -133
- package/dist/common/sync-message-types.d.ts.map +1 -1
- package/dist/common/sync-message-types.js +26 -14
- package/dist/common/sync-message-types.js.map +1 -1
- package/dist/common/ws-rpc-schema.d.ts +33 -34
- package/dist/common/ws-rpc-schema.d.ts.map +1 -1
- package/dist/common/ws-rpc-schema.js +5 -5
- package/dist/common/ws-rpc-schema.js.map +1 -1
- package/package.json +42 -58
- package/src/cf-worker/do/durable-object.ts +70 -64
- package/src/cf-worker/do/layer.ts +142 -99
- package/src/cf-worker/do/observability.test.ts +337 -0
- package/src/cf-worker/do/observability.ts +121 -0
- package/src/cf-worker/do/pull.ts +28 -28
- package/src/cf-worker/do/push.test.ts +40 -0
- package/src/cf-worker/do/push.ts +139 -115
- package/src/cf-worker/do/sqlite.ts +1 -1
- package/src/cf-worker/do/sync-storage.ts +34 -21
- package/src/cf-worker/do/transport/do-rpc-server.test.ts +32 -0
- package/src/cf-worker/do/transport/do-rpc-server.ts +46 -35
- package/src/cf-worker/do/transport/http-rpc-server.ts +7 -10
- package/src/cf-worker/do/transport/ws-rpc-server.ts +52 -28
- package/src/cf-worker/shared.ts +29 -17
- package/src/cf-worker/worker.ts +21 -22
- package/src/client/transport/do-rpc-client.test.ts +411 -0
- package/src/client/transport/do-rpc-client.ts +175 -51
- package/src/client/transport/http-rpc-client.ts +66 -45
- package/src/client/transport/rpc-client-error.test.ts +41 -0
- package/src/client/transport/rpc-client-error.ts +9 -0
- package/src/client/transport/ws-rpc-client.ts +40 -32
- package/src/common/do-rpc-schema.ts +13 -3
- package/src/common/http-rpc-schema.ts +5 -5
- package/src/common/mod.ts +4 -4
- package/src/common/sync-message-types.ts +16 -16
- package/src/common/ws-rpc-schema.ts +4 -4
|
@@ -1,51 +1,69 @@
|
|
|
1
1
|
import { UnknownError } from '@livestore/common';
|
|
2
2
|
import { toDurableObjectHandler } from '@livestore/common-cf';
|
|
3
|
-
import { Effect, Headers,
|
|
4
|
-
import { SyncDoRpc } from
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
import { Effect, Headers, Option, Stream } from '@livestore/utils/effect';
|
|
4
|
+
import { SyncDoRpc } from '../../../common/do-rpc-schema.js';
|
|
5
|
+
import { rpcSubscriptionKeyPrefix } from '../../shared.js';
|
|
6
|
+
import * as DoCtx from '../layer.js';
|
|
7
|
+
import { makeRpcSpanOptions, withRpcStreamSpan } from '../observability.js';
|
|
8
|
+
import { makeEndingPullStream } from '../pull.js';
|
|
9
|
+
import { makePush } from '../push.js';
|
|
10
|
+
/**
|
|
11
|
+
* Drops a live-pull subscription row only if it still belongs to the pull that asked. A replacement store booted on
|
|
12
|
+
* the same client DO while a slow shutdown is still draining overwrites the row with its own request id, and the
|
|
13
|
+
* earlier pull's late unsubscribe must not take that subscription down.
|
|
14
|
+
*/
|
|
15
|
+
export const dropRpcSubscription = (kv, { durableObjectId, requestId }) => {
|
|
16
|
+
const key = `${rpcSubscriptionKeyPrefix}${durableObjectId}`;
|
|
17
|
+
if (kv.get(key)?.requestId === requestId) {
|
|
18
|
+
kv.delete(key);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
export const createDoRpcHandler = (options) => Effect.gen({ self: this }, function* () {
|
|
22
|
+
const { payload, input, observability } = options;
|
|
23
|
+
const parent = yield* Effect.currentParentSpan.pipe(Effect.option);
|
|
12
24
|
// TODO add admin RPCs
|
|
13
25
|
const RpcLive = SyncDoRpc.toLayer({
|
|
14
|
-
'SyncDoRpc.Ping': (
|
|
15
|
-
|
|
16
|
-
},
|
|
17
|
-
|
|
18
|
-
const { rpcSubscriptions } = yield* DoCtx;
|
|
26
|
+
'SyncDoRpc.Ping': () => Effect.void,
|
|
27
|
+
'SyncDoRpc.Unsubscribe': (req) => Effect.sync(() => dropRpcSubscription(input.doSelf.ctx.storage.kv, req)),
|
|
28
|
+
'SyncDoRpc.Pull': (req, { headers }) => Effect.gen({ self: this }, function* () {
|
|
29
|
+
const { ctx } = yield* DoCtx.DoCtx;
|
|
19
30
|
// TODO rename `req.rpcContext` to something more appropriate
|
|
20
31
|
if (req.rpcContext !== undefined) {
|
|
21
|
-
|
|
32
|
+
const subscription = {
|
|
22
33
|
storeId: req.storeId,
|
|
23
34
|
subscribedAt: Date.now(),
|
|
24
35
|
requestId: Headers.get(headers, 'x-rpc-request-id').pipe(Option.getOrThrow),
|
|
25
36
|
callerContext: req.rpcContext.callerContext,
|
|
26
37
|
...(req.payload !== undefined ? { payload: req.payload } : {}),
|
|
27
|
-
}
|
|
38
|
+
};
|
|
39
|
+
// Keyed by client DO id (not storeId — one backend serves many client DOs). The DO's synchronous KV
|
|
40
|
+
// storage is the single source of truth, so the entry outlives backend reconstruction.
|
|
41
|
+
ctx.storage.kv.put(`${rpcSubscriptionKeyPrefix}${subscription.callerContext.durableObjectId}`, subscription);
|
|
28
42
|
}
|
|
29
43
|
// DO-RPC doesn't have HTTP headers context - headers are undefined
|
|
30
44
|
return makeEndingPullStream({ req, payload: req.payload, headers: undefined });
|
|
31
45
|
}).pipe(Stream.unwrap, Stream.map((res) => ({
|
|
32
46
|
...res,
|
|
33
47
|
rpcRequestId: Headers.get(headers, 'x-rpc-request-id').pipe(Option.getOrThrow),
|
|
34
|
-
})), Stream.
|
|
48
|
+
})), Stream.provide(DoCtx.layer({ ...input, from: { storeId: req.storeId } })), Stream.mapError((cause) => cause._tag === 'UnknownError' || cause._tag === 'BackendIdMismatchError'
|
|
35
49
|
? cause
|
|
36
|
-
: new UnknownError({ cause })), Stream.
|
|
37
|
-
|
|
38
|
-
|
|
50
|
+
: new UnknownError({ cause })), Stream.tapCause(Effect.log),
|
|
51
|
+
// The bridge runs this stream in a separate runtime. Install telemetry there too.
|
|
52
|
+
(_) => withRpcStreamSpan(_, 'RpcServer.SyncDoRpc.Pull', makeRpcSpanOptions(parent)), observability.stream),
|
|
53
|
+
'SyncDoRpc.Push': (req) => Effect.gen({ self: this }, function* () {
|
|
54
|
+
const { doOptions, ctx, env, storeId } = yield* DoCtx.DoCtx;
|
|
39
55
|
// DO-RPC doesn't have HTTP headers context - headers are undefined
|
|
40
56
|
const push = makePush({ storeId, payload: req.payload, headers: undefined, options: doOptions, ctx, env });
|
|
41
57
|
return yield* push(req);
|
|
42
|
-
}).pipe(Effect.provide(DoCtx.
|
|
58
|
+
}).pipe(Effect.provide(DoCtx.layer({ ...input, from: { storeId: req.storeId } })), Effect.mapError((cause) => cause._tag === 'UnknownError' ||
|
|
59
|
+
cause._tag === 'ServerAheadError' ||
|
|
60
|
+
cause._tag === 'BackendIdMismatchError'
|
|
43
61
|
? cause
|
|
44
62
|
: new UnknownError({ cause })), Effect.tapCauseLogPretty),
|
|
45
63
|
});
|
|
46
64
|
const handler = toDurableObjectHandler(SyncDoRpc, {
|
|
47
|
-
layer:
|
|
65
|
+
layer: RpcLive,
|
|
48
66
|
});
|
|
49
|
-
return yield* handler(payload);
|
|
67
|
+
return yield* handler(payload).pipe(Effect.annotateLogs({ thread: 'SyncDo' }));
|
|
50
68
|
}).pipe(Effect.withSpan('createDoRpcHandler'));
|
|
51
69
|
//# sourceMappingURL=do-rpc-server.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"do-rpc-server.js","sourceRoot":"","sources":["../../../../src/cf-worker/do/transport/do-rpc-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAgB,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,
|
|
1
|
+
{"version":3,"file":"do-rpc-server.js","sourceRoot":"","sources":["../../../../src/cf-worker/do/transport/do-rpc-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"do-rpc-server.test.d.ts","sourceRoot":"","sources":["../../../../src/cf-worker/do/transport/do-rpc-server.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Vitest } from '@livestore/utils-dev/node-vitest';
|
|
2
|
+
import { rpcSubscriptionKeyPrefix } from '../../shared.js';
|
|
3
|
+
import { dropRpcSubscription } from './do-rpc-server.js';
|
|
4
|
+
const durableObjectId = 'client-do';
|
|
5
|
+
const key = `${rpcSubscriptionKeyPrefix}${durableObjectId}`;
|
|
6
|
+
const subscribedWith = (requestId) => {
|
|
7
|
+
const rows = new Map([
|
|
8
|
+
[
|
|
9
|
+
key,
|
|
10
|
+
{ storeId: 'store', subscribedAt: 0, requestId, callerContext: { bindingName: 'CLIENT_DO', durableObjectId } },
|
|
11
|
+
],
|
|
12
|
+
]);
|
|
13
|
+
return { rows, kv: { get: (k) => rows.get(k), delete: (k) => rows.delete(k) } };
|
|
14
|
+
};
|
|
15
|
+
Vitest.describe('sync-cf DO-RPC unsubscribe', () => {
|
|
16
|
+
// A replacement pull overwrote the row with its own request id; the earlier pull's late unsubscribe must be a no-op.
|
|
17
|
+
Vitest.test('keeps the row when the request id was superseded', () => {
|
|
18
|
+
const { rows, kv } = subscribedWith('pull-2');
|
|
19
|
+
dropRpcSubscription(kv, { durableObjectId, requestId: 'pull-1' });
|
|
20
|
+
Vitest.expect(rows.has(key)).toBe(true);
|
|
21
|
+
});
|
|
22
|
+
Vitest.test('drops the row for the pull that registered it', () => {
|
|
23
|
+
const { rows, kv } = subscribedWith('pull-1');
|
|
24
|
+
dropRpcSubscription(kv, { durableObjectId, requestId: 'pull-1' });
|
|
25
|
+
Vitest.expect(rows.has(key)).toBe(false);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=do-rpc-server.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"do-rpc-server.test.js","sourceRoot":"","sources":["../../../../src/cf-worker/do/transport/do-rpc-server.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAA;AAEzD,OAAO,EAAwB,wBAAwB,EAAE,MAAM,iBAAiB,CAAA;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAExD,MAAM,eAAe,GAAG,WAAW,CAAA;AACnC,MAAM,GAAG,GAAG,GAAG,wBAAwB,GAAG,eAAe,EAAE,CAAA;AAE3D,MAAM,cAAc,GAAG,CAAC,SAAiB,EAAE,EAAE;IAC3C,MAAM,IAAI,GAAG,IAAI,GAAG,CAA0B;QAC5C;YACE,GAAG;YACH,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,EAAE,SAAS,EAAE,aAAa,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,EAAE;SAC/G;KACF,CAAC,CAAA;IACF,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;AACjG,CAAC,CAAA;AAED,MAAM,CAAC,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IACjD,qHAAqH;IACrH,MAAM,CAAC,IAAI,CAAC,kDAAkD,EAAE,GAAG,EAAE;QACnE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;QAC7C,mBAAmB,CAAC,EAAE,EAAE,EAAE,eAAe,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAA;QACjE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,IAAI,CAAC,+CAA+C,EAAE,GAAG,EAAE;QAChE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;QAC7C,mBAAmB,CAAC,EAAE,EAAE,EAAE,eAAe,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAA;QACjE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC1C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { CfTypes } from '@livestore/common-cf';
|
|
2
2
|
import { Effect } from '@livestore/utils/effect';
|
|
3
|
-
import
|
|
3
|
+
import * as DoCtx from '../layer.ts';
|
|
4
4
|
export declare const createHttpRpcHandler: (args_0: {
|
|
5
5
|
request: CfTypes.Request;
|
|
6
6
|
responseHeaders?: Record<string, string>;
|
|
7
7
|
forwardedHeaders?: Record<string, string>;
|
|
8
|
-
}) => Effect.Effect<CfTypes.Response, import("effect/Cause").
|
|
8
|
+
}) => Effect.Effect<CfTypes.Response, import("effect/Cause").TimeoutError, DoCtx.DoCtx | import("effect/Scope").Scope>;
|
|
9
9
|
//# sourceMappingURL=http-rpc-server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-rpc-server.d.ts","sourceRoot":"","sources":["../../../../src/cf-worker/do/transport/http-rpc-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACnD,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"http-rpc-server.d.ts","sourceRoot":"","sources":["../../../../src/cf-worker/do/transport/http-rpc-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACnD,OAAO,EAAE,MAAM,EAAkD,MAAM,yBAAyB,CAAA;AAKhG,OAAO,KAAK,KAAK,MAAM,aAAa,CAAA;AAIpC,eAAO,MAAM,oBAAoB;aAKtB,OAAO,CAAC,OAAO;sBACN,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;uBACrB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;sHAiBzC,CAAA"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { Effect,
|
|
2
|
-
import { SyncHttpRpc } from
|
|
3
|
-
import * as SyncMessage from
|
|
4
|
-
import { headersRecordToMap } from
|
|
5
|
-
import
|
|
6
|
-
import { makeEndingPullStream } from
|
|
7
|
-
import { makePush } from
|
|
1
|
+
import { Effect, HttpEffect, Layer, RpcSerialization, RpcServer } from '@livestore/utils/effect';
|
|
2
|
+
import { SyncHttpRpc } from '../../../common/http-rpc-schema.js';
|
|
3
|
+
import * as SyncMessage from '../../../common/sync-message-types.js';
|
|
4
|
+
import { headersRecordToMap } from '../../shared.js';
|
|
5
|
+
import * as DoCtx from '../layer.js';
|
|
6
|
+
import { makeEndingPullStream } from '../pull.js';
|
|
7
|
+
import { makePush } from '../push.js';
|
|
8
8
|
export const createHttpRpcHandler = Effect.fn('createHttpRpcHandler')(function* ({ request, responseHeaders, forwardedHeaders, }) {
|
|
9
9
|
const handlerLayer = createHttpRpcLayer(forwardedHeaders);
|
|
10
|
-
const
|
|
11
|
-
const webHandler =
|
|
10
|
+
const httpEffect = yield* RpcServer.toHttpEffect(SyncHttpRpc).pipe(Effect.provide(handlerLayer));
|
|
11
|
+
const webHandler = HttpEffect.toWebHandler(httpEffect);
|
|
12
12
|
const response = yield* Effect.promise(() => webHandler(request)).pipe(Effect.timeout(10000));
|
|
13
13
|
if (responseHeaders !== undefined) {
|
|
14
14
|
for (const [key, value] of Object.entries(responseHeaders)) {
|
|
@@ -23,11 +23,11 @@ const createHttpRpcLayer = (forwardedHeaders) => {
|
|
|
23
23
|
return SyncHttpRpc.toLayer({
|
|
24
24
|
'SyncHttpRpc.Pull': (req) => makeEndingPullStream({ req, payload: req.payload, headers }),
|
|
25
25
|
'SyncHttpRpc.Push': (req) => Effect.gen(function* () {
|
|
26
|
-
const { ctx, env, doOptions, storeId } = yield* DoCtx;
|
|
27
|
-
const push = makePush({ payload:
|
|
26
|
+
const { ctx, env, doOptions, storeId } = yield* DoCtx.DoCtx;
|
|
27
|
+
const push = makePush({ payload: req.payload, headers, options: doOptions, storeId, ctx, env });
|
|
28
28
|
return yield* push(req);
|
|
29
29
|
}),
|
|
30
30
|
'SyncHttpRpc.Ping': () => Effect.succeed(SyncMessage.Pong.make({})),
|
|
31
|
-
}).pipe(Layer.provideMerge(
|
|
31
|
+
}).pipe(Layer.provideMerge(RpcSerialization.layerJson));
|
|
32
32
|
};
|
|
33
33
|
//# sourceMappingURL=http-rpc-server.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-rpc-server.js","sourceRoot":"","sources":["../../../../src/cf-worker/do/transport/http-rpc-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"http-rpc-server.js","sourceRoot":"","sources":["../../../../src/cf-worker/do/transport/http-rpc-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAEhG,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAA;AAChE,OAAO,KAAK,WAAW,MAAM,uCAAuC,CAAA;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACpD,OAAO,KAAK,KAAK,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,EAAE,CAAC,sBAAsB,CAAC,CAAC,QAAQ,CAAC,EAAE,EAC/E,OAAO,EACP,eAAe,EACf,gBAAgB,GAKjB;IACC,MAAM,YAAY,GAAG,kBAAkB,CAAC,gBAAgB,CAAC,CAAA;IACzD,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAA;IAChG,MAAM,UAAU,GAAG,UAAU,CAAC,YAAY,CAAC,UAAU,CAAC,CAAA;IAEtD,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CACpC,GAAG,EAAE,CAAC,UAAU,CAAC,OAA0B,CAAsC,CAClF,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAA;IAE7B,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;YAC3D,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QAClC,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAC,CAAA;AAEF,MAAM,kBAAkB,GAAG,CAAC,gBAAoD,EAAE,EAAE;IAClF,MAAM,OAAO,GAAG,kBAAkB,CAAC,gBAAgB,CAAC,CAAA;IAEpD,gCAAgC;IAChC,OAAO,WAAW,CAAC,OAAO,CAAC;QACzB,kBAAkB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,oBAAoB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;QAEzF,kBAAkB,EAAE,CAAC,GAAG,EAAE,EAAE,CAC1B,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAA;YAC3D,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAA;YAE/F,OAAO,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACzB,CAAC,CAAC;QAEJ,kBAAkB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;KACpE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAA;AACzD,CAAC,CAAA"}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { WsContext } from '@livestore/common-cf';
|
|
2
2
|
import { Layer, RpcServer } from '@livestore/utils/effect';
|
|
3
|
-
import
|
|
4
|
-
|
|
3
|
+
import * as DoCtx from '../layer.ts';
|
|
4
|
+
import { type makeObservability } from '../observability.ts';
|
|
5
|
+
export declare const makeRpcServer: ({ doSelf, doOptions, observability, }: Omit<DoCtx.DoCtxInput, 'from'> & {
|
|
6
|
+
observability: ReturnType<typeof makeObservability>;
|
|
7
|
+
}) => Layer.Layer<never, never, RpcServer.Protocol | WsContext>;
|
|
8
|
+
/** Production handler layer, exported so transport tests can exercise the exact RPC composition in memory. */
|
|
9
|
+
export declare const makeRpcHandlers: ({ doSelf, doOptions, observability, }: Omit<DoCtx.DoCtxInput, 'from'> & {
|
|
10
|
+
observability: ReturnType<typeof makeObservability>;
|
|
11
|
+
}) => Layer.Layer<import("effect/rpc/Rpc").Handler<"SyncWsRpc.Pull"> | import("effect/rpc/Rpc").Handler<"SyncWsRpc.Push">, never, WsContext>;
|
|
5
12
|
//# sourceMappingURL=ws-rpc-server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ws-rpc-server.d.ts","sourceRoot":"","sources":["../../../../src/cf-worker/do/transport/ws-rpc-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAoB,KAAK,
|
|
1
|
+
{"version":3,"file":"ws-rpc-server.d.ts","sourceRoot":"","sources":["../../../../src/cf-worker/do/transport/ws-rpc-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAoB,KAAK,EAAU,SAAS,EAAkB,MAAM,yBAAyB,CAAA;AAIpG,OAAO,KAAK,KAAK,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,KAAK,iBAAiB,EAAkD,MAAM,qBAAqB,CAAA;AAI5G,eAAO,MAAM,aAAa,0CAIvB,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG;IAAE,aAAa,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAA;CAAE,8DAI1F,CAAA;AAED,8GAA8G;AAC9G,eAAO,MAAM,eAAe,0CAIzB,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG;IAAE,aAAa,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAA;CAAE,2IA4CvF,CAAA"}
|
|
@@ -1,43 +1,51 @@
|
|
|
1
1
|
import { UnknownError } from '@livestore/common';
|
|
2
2
|
import { WsContext } from '@livestore/common-cf';
|
|
3
|
-
import { Effect, identity, Layer, RpcServer, Schema, Stream } from '@livestore/utils/effect';
|
|
4
|
-
import { SyncWsRpc } from
|
|
5
|
-
import { headersRecordToMap, WebSocketAttachmentSchema } from
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const headers = yield* getForwardedHeaders;
|
|
13
|
-
return makeEndingPullStream({ req, payload: req.payload, headers }).pipe(
|
|
14
|
-
// Needed to keep the stream alive on the client side for phase 2 (i.e. not send the `Exit` stream RPC message)
|
|
15
|
-
req.live === true ? Stream.concat(Stream.never) : identity, Stream.provideLayer(DoCtx.Default({ doSelf, doOptions, from: { storeId: req.storeId } })), Stream.mapError((cause) => cause._tag === 'UnknownError' || cause._tag === 'BackendIdMismatchError'
|
|
16
|
-
? cause
|
|
17
|
-
: new UnknownError({ cause })));
|
|
18
|
-
}).pipe(Stream.unwrap),
|
|
19
|
-
'SyncWsRpc.Push': (req) => Effect.gen(function* () {
|
|
20
|
-
const { doOptions, storeId, ctx, env } = yield* DoCtx;
|
|
21
|
-
const headers = yield* getForwardedHeaders;
|
|
22
|
-
const push = makePush({ options: doOptions, storeId, payload: req.payload, headers, ctx, env });
|
|
23
|
-
return yield* push(req);
|
|
24
|
-
}).pipe(Effect.provide(DoCtx.Default({ doSelf, doOptions, from: { storeId: req.storeId } })), Effect.mapError((cause) => cause._tag === 'UnknownError' || cause._tag === 'ServerAheadError' || cause._tag === 'BackendIdMismatchError'
|
|
25
|
-
? cause
|
|
26
|
-
: new UnknownError({ cause })), Effect.tapCauseLogPretty),
|
|
27
|
-
});
|
|
3
|
+
import { Effect, identity, Layer, Result, RpcServer, Schema, Stream } from '@livestore/utils/effect';
|
|
4
|
+
import { SyncWsRpc } from '../../../common/ws-rpc-schema.js';
|
|
5
|
+
import { headersRecordToMap, WebSocketAttachmentSchema } from '../../shared.js';
|
|
6
|
+
import * as DoCtx from '../layer.js';
|
|
7
|
+
import { rpcSpanOptions, withRpcSpan, withRpcStreamSpan } from '../observability.js';
|
|
8
|
+
import { makeEndingPullStream } from '../pull.js';
|
|
9
|
+
import { makePush } from '../push.js';
|
|
10
|
+
export const makeRpcServer = ({ doSelf, doOptions, observability, }) => {
|
|
11
|
+
const handlersLayer = makeRpcHandlers({ doSelf, doOptions, observability });
|
|
28
12
|
return RpcServer.layer(SyncWsRpc).pipe(Layer.provide(handlersLayer));
|
|
29
13
|
};
|
|
14
|
+
/** Production handler layer, exported so transport tests can exercise the exact RPC composition in memory. */
|
|
15
|
+
export const makeRpcHandlers = ({ doSelf, doOptions, observability, }) => SyncWsRpc.toLayer({
|
|
16
|
+
'SyncWsRpc.Pull': (req) => Effect.gen(function* () {
|
|
17
|
+
const spanOptions = yield* rpcSpanOptions;
|
|
18
|
+
const headers = yield* getForwardedHeaders;
|
|
19
|
+
return makeEndingPullStream({ req, payload: req.payload, headers }).pipe(Stream.provide(DoCtx.layer({ doSelf, doOptions, from: { storeId: req.storeId } })), Stream.mapError((cause) => cause._tag === 'UnknownError' || cause._tag === 'BackendIdMismatchError'
|
|
20
|
+
? cause
|
|
21
|
+
: new UnknownError({ cause })), (_) => withRpcStreamSpan(_, 'RpcServer.SyncWsRpc.Pull', spanOptions));
|
|
22
|
+
}).pipe(Stream.unwrap,
|
|
23
|
+
// Drain finite history before entering the live phase, which survives DO hibernation.
|
|
24
|
+
observability.stream,
|
|
25
|
+
// Keep the client subscription open without retaining an exporter scope or timer.
|
|
26
|
+
req.live === true ? Stream.concat(Stream.never) : identity),
|
|
27
|
+
'SyncWsRpc.Push': (req) => Effect.flatMap(rpcSpanOptions, (spanOptions) => Effect.gen(function* () {
|
|
28
|
+
const { doOptions, storeId, ctx, env } = yield* DoCtx.DoCtx;
|
|
29
|
+
const headers = yield* getForwardedHeaders;
|
|
30
|
+
const push = makePush({ options: doOptions, storeId, payload: req.payload, headers, ctx, env });
|
|
31
|
+
return yield* push(req);
|
|
32
|
+
}).pipe(Effect.provide(DoCtx.layer({ doSelf, doOptions, from: { storeId: req.storeId } })), Effect.mapError((cause) => cause._tag === 'UnknownError' ||
|
|
33
|
+
cause._tag === 'ServerAheadError' ||
|
|
34
|
+
cause._tag === 'BackendIdMismatchError'
|
|
35
|
+
? cause
|
|
36
|
+
: new UnknownError({ cause })), Effect.tapCauseLogPretty, (_) => withRpcSpan(_, 'RpcServer.SyncWsRpc.Push', spanOptions))).pipe(observability.effect),
|
|
37
|
+
});
|
|
30
38
|
/** Extracts forwarded headers from the WebSocket attachment */
|
|
31
39
|
const getForwardedHeaders = Effect.gen(function* () {
|
|
32
40
|
const { ws } = yield* WsContext;
|
|
33
41
|
const attachment = ws.deserializeAttachment();
|
|
34
|
-
const decoded = Schema.
|
|
35
|
-
if (decoded
|
|
36
|
-
yield* Effect.logError('Failed to decode WebSocket attachment for forwarded headers', { error: decoded.
|
|
42
|
+
const decoded = Schema.decodeUnknownResult(WebSocketAttachmentSchema)(attachment);
|
|
43
|
+
if (Result.isFailure(decoded) === true) {
|
|
44
|
+
yield* Effect.logError('Failed to decode WebSocket attachment for forwarded headers', { error: decoded.failure });
|
|
37
45
|
ws.close(1011, 'invalid-attachment');
|
|
38
46
|
return yield* Effect.die('Invalid WebSocket attachment (headers decode failed)');
|
|
39
47
|
}
|
|
40
|
-
const headers = headersRecordToMap(decoded.
|
|
48
|
+
const headers = headersRecordToMap(decoded.success.headers);
|
|
41
49
|
return headers;
|
|
42
50
|
});
|
|
43
51
|
//# sourceMappingURL=ws-rpc-server.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ws-rpc-server.js","sourceRoot":"","sources":["../../../../src/cf-worker/do/transport/ws-rpc-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"ws-rpc-server.js","sourceRoot":"","sources":["../../../../src/cf-worker/do/transport/ws-rpc-server.ts"],"names":[],"mappings":"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"}
|
package/dist/cf-worker/mod.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { CfDeclare } from '@livestore/common-cf/declare';
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
2
|
+
export * from './do/durable-object.js';
|
|
3
|
+
export * from './shared.js';
|
|
4
|
+
export * from './worker.js';
|
|
5
5
|
//# sourceMappingURL=mod.js.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { UnknownError } from '@livestore/common';
|
|
2
2
|
import type { CfTypes } from '@livestore/common-cf';
|
|
3
|
-
import { Effect,
|
|
3
|
+
import type { Effect, Layer } from '@livestore/utils/effect';
|
|
4
|
+
import { Schema } from '@livestore/utils/effect';
|
|
4
5
|
import type { SearchParams } from '../common/mod.ts';
|
|
5
6
|
import { SyncMessage } from '../common/mod.ts';
|
|
6
7
|
export type Env = {};
|
|
@@ -15,7 +16,7 @@ export type ForwardHeadersOption = readonly string[] | ((request: CfTypes.Reques
|
|
|
15
16
|
/** Context passed to onPush/onPull callbacks */
|
|
16
17
|
export type CallbackContext = {
|
|
17
18
|
storeId: StoreId;
|
|
18
|
-
payload?: Schema.
|
|
19
|
+
payload?: Schema.Json;
|
|
19
20
|
/** Headers forwarded from the request (only present if `forwardHeaders` is configured) */
|
|
20
21
|
headers?: ForwardedHeaders;
|
|
21
22
|
};
|
|
@@ -101,10 +102,15 @@ export type MakeDurableObjectClassOptions = {
|
|
|
101
102
|
http?: {
|
|
102
103
|
responseHeaders?: Record<string, string>;
|
|
103
104
|
};
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
/** Optional telemetry. Omit to avoid creating an exporter or sending telemetry. */
|
|
106
|
+
otel?: SyncBackendOtelOptions;
|
|
107
|
+
};
|
|
108
|
+
export type SyncBackendOtelOptions =
|
|
109
|
+
/** Application-supplied tracer layer; LiveStore builds and finalizes its resources per sync operation. */
|
|
110
|
+
Layer.Layer<never> | {
|
|
111
|
+
/** Convenience OTLP/HTTP JSON exporter owned by LiveStore for each operation. */
|
|
112
|
+
baseUrl?: string;
|
|
113
|
+
serviceName?: string;
|
|
108
114
|
};
|
|
109
115
|
export type StoreId = string;
|
|
110
116
|
export type DurableObjectId = string;
|
|
@@ -125,13 +131,8 @@ export type DurableObjectId = string;
|
|
|
125
131
|
* and old data becomes inaccessible (but remains in storage).
|
|
126
132
|
*/
|
|
127
133
|
export declare const PERSISTENCE_FORMAT_VERSION = 7;
|
|
128
|
-
export declare const encodeOutgoingMessage: (
|
|
129
|
-
readonly backendId: string;
|
|
134
|
+
export declare const encodeOutgoingMessage: (input: {} | {
|
|
130
135
|
readonly batch: readonly {
|
|
131
|
-
readonly metadata: import("effect/Option").Option<{
|
|
132
|
-
readonly createdAt: string;
|
|
133
|
-
readonly _tag: "SyncMessage.SyncMetadata";
|
|
134
|
-
}>;
|
|
135
136
|
readonly eventEncoded: {
|
|
136
137
|
readonly name: string;
|
|
137
138
|
readonly args: any;
|
|
@@ -140,6 +141,10 @@ export declare const encodeOutgoingMessage: (a: {
|
|
|
140
141
|
readonly clientId: string;
|
|
141
142
|
readonly sessionId: string;
|
|
142
143
|
};
|
|
144
|
+
readonly metadata: import("effect/Option").Option<{
|
|
145
|
+
readonly _tag: "SyncMessage.SyncMetadata";
|
|
146
|
+
readonly createdAt: string;
|
|
147
|
+
}>;
|
|
143
148
|
}[];
|
|
144
149
|
readonly pageInfo: {
|
|
145
150
|
readonly _tag: "MoreUnknown";
|
|
@@ -149,23 +154,18 @@ export declare const encodeOutgoingMessage: (a: {
|
|
|
149
154
|
} | {
|
|
150
155
|
readonly _tag: "NoMore";
|
|
151
156
|
};
|
|
152
|
-
|
|
157
|
+
readonly backendId: string;
|
|
158
|
+
} | {
|
|
153
159
|
readonly _tag: "SyncMessage.Pong";
|
|
154
160
|
} | {
|
|
155
161
|
readonly _tag: "SyncMessage.AdminResetRoomResponse";
|
|
156
162
|
} | {
|
|
163
|
+
readonly _tag: "SyncMessage.AdminInfoResponse";
|
|
157
164
|
readonly info: {
|
|
158
165
|
readonly durableObjectId: string;
|
|
159
166
|
};
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
export declare const encodeIncomingMessage: (a: {
|
|
163
|
-
readonly cursor: import("effect/Option").Option<{
|
|
164
|
-
readonly backendId: string;
|
|
165
|
-
readonly eventSequenceNumber: number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">;
|
|
166
|
-
}>;
|
|
167
|
-
} | {
|
|
168
|
-
readonly backendId: import("effect/Option").Option<string>;
|
|
167
|
+
}, options?: import("effect/SchemaAST").ParseOptions) => string;
|
|
168
|
+
export declare const encodeIncomingMessage: (input: {
|
|
169
169
|
readonly batch: readonly {
|
|
170
170
|
readonly name: string;
|
|
171
171
|
readonly args: any;
|
|
@@ -174,6 +174,12 @@ export declare const encodeIncomingMessage: (a: {
|
|
|
174
174
|
readonly clientId: string;
|
|
175
175
|
readonly sessionId: string;
|
|
176
176
|
}[];
|
|
177
|
+
readonly backendId: import("effect/Option").Option<string>;
|
|
178
|
+
} | {
|
|
179
|
+
readonly cursor: import("effect/Option").Option<{
|
|
180
|
+
readonly backendId: string;
|
|
181
|
+
readonly eventSequenceNumber: number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">;
|
|
182
|
+
}>;
|
|
177
183
|
} | {
|
|
178
184
|
readonly _tag: "SyncMessage.Ping";
|
|
179
185
|
} | {
|
|
@@ -182,7 +188,7 @@ export declare const encodeIncomingMessage: (a: {
|
|
|
182
188
|
} | {
|
|
183
189
|
readonly _tag: "SyncMessage.AdminInfoRequest";
|
|
184
190
|
readonly adminSecret: string;
|
|
185
|
-
},
|
|
191
|
+
}, options?: import("effect/SchemaAST").ParseOptions) => string;
|
|
186
192
|
/**
|
|
187
193
|
* Extracts the LiveStore sync search parameters from a request. Returns
|
|
188
194
|
* `undefined` when the request does not carry valid sync metadata so callers
|
|
@@ -191,7 +197,7 @@ export declare const encodeIncomingMessage: (a: {
|
|
|
191
197
|
export declare const matchSyncRequest: (request: CfTypes.Request) => SearchParams | undefined;
|
|
192
198
|
export type RpcSubscription = {
|
|
193
199
|
storeId: StoreId;
|
|
194
|
-
payload?: Schema.
|
|
200
|
+
payload?: Schema.Json;
|
|
195
201
|
subscribedAt: number;
|
|
196
202
|
/** Effect RPC request ID */
|
|
197
203
|
requestId: string;
|
|
@@ -200,6 +206,8 @@ export type RpcSubscription = {
|
|
|
200
206
|
durableObjectId: string;
|
|
201
207
|
};
|
|
202
208
|
};
|
|
209
|
+
/** Key prefix for DO-RPC subscriptions persisted in the DO's synchronous KV storage. */
|
|
210
|
+
export declare const rpcSubscriptionKeyPrefix = "rpc-sub:";
|
|
203
211
|
/**
|
|
204
212
|
* Durable Object interface supporting the DO RPC protocol for DO <> DO syncing.
|
|
205
213
|
*/
|
|
@@ -207,11 +215,11 @@ export interface SyncBackendRpcInterface {
|
|
|
207
215
|
__DURABLE_OBJECT_BRAND: never;
|
|
208
216
|
rpc(payload: Uint8Array): Promise<Uint8Array | CfTypes.ReadableStream>;
|
|
209
217
|
}
|
|
210
|
-
export declare const WebSocketAttachmentSchema: Schema.
|
|
211
|
-
storeId:
|
|
212
|
-
payload: Schema.optional<Schema.
|
|
213
|
-
pullRequestIds: Schema.
|
|
214
|
-
headers: Schema.optional<Schema
|
|
218
|
+
export declare const WebSocketAttachmentSchema: Schema.fromJsonString<Schema.Struct<{
|
|
219
|
+
readonly storeId: Schema.String;
|
|
220
|
+
readonly payload: Schema.optional<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
221
|
+
readonly pullRequestIds: Schema.$Array<Schema.Union<readonly [Schema.String, Schema.Finite]>>;
|
|
222
|
+
readonly headers: Schema.optional<Schema.$Record<Schema.String, Schema.String>>;
|
|
215
223
|
}>>;
|
|
216
224
|
/** Helper to extract headers from a request based on the forwardHeaders option */
|
|
217
225
|
export declare const extractForwardedHeaders: (request: CfTypes.Request, forwardHeaders: ForwardHeadersOption | undefined) => Record<string, string> | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/cf-worker/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/cf-worker/shared.ts"],"names":[],"mappings":"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"}
|
package/dist/cf-worker/shared.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { SearchParamsSchema, SyncMessage } from
|
|
1
|
+
import { Result, Schema } from '@livestore/utils/effect';
|
|
2
|
+
import { SearchParamsSchema, SyncMessage } from '../common/mod.js';
|
|
3
3
|
/**
|
|
4
4
|
* CRITICAL: Increment this version whenever you modify the database schema structure.
|
|
5
5
|
*
|
|
@@ -17,8 +17,9 @@ import { SearchParamsSchema, SyncMessage } from "../common/mod.js";
|
|
|
17
17
|
* and old data becomes inaccessible (but remains in storage).
|
|
18
18
|
*/
|
|
19
19
|
export const PERSISTENCE_FORMAT_VERSION = 7;
|
|
20
|
-
export const encodeOutgoingMessage = Schema.encodeSync(Schema.
|
|
21
|
-
export const encodeIncomingMessage = Schema.encodeSync(Schema.
|
|
20
|
+
export const encodeOutgoingMessage = Schema.encodeSync(Schema.fromJsonString(SyncMessage.BackendToClientMessage));
|
|
21
|
+
export const encodeIncomingMessage = Schema.encodeSync(Schema.fromJsonString(SyncMessage.ClientToBackendMessage));
|
|
22
|
+
const SearchParamsFromUrlSearchParams = Schema.fromURLSearchParams(SearchParamsSchema);
|
|
22
23
|
/**
|
|
23
24
|
* Extracts the LiveStore sync search parameters from a request. Returns
|
|
24
25
|
* `undefined` when the request does not carry valid sync metadata so callers
|
|
@@ -26,21 +27,22 @@ export const encodeIncomingMessage = Schema.encodeSync(Schema.parseJson(SyncMess
|
|
|
26
27
|
*/
|
|
27
28
|
export const matchSyncRequest = (request) => {
|
|
28
29
|
const url = new URL(request.url);
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
if (paramsResult._tag === 'None') {
|
|
30
|
+
const paramsResult = Schema.decodeResult(SearchParamsFromUrlSearchParams)(url.searchParams);
|
|
31
|
+
if (Result.isFailure(paramsResult) === true) {
|
|
32
32
|
return undefined;
|
|
33
33
|
}
|
|
34
|
-
return paramsResult.
|
|
34
|
+
return paramsResult.success;
|
|
35
35
|
};
|
|
36
|
-
|
|
36
|
+
/** Key prefix for DO-RPC subscriptions persisted in the DO's synchronous KV storage. */
|
|
37
|
+
export const rpcSubscriptionKeyPrefix = 'rpc-sub:';
|
|
38
|
+
export const WebSocketAttachmentSchema = Schema.fromJsonString(Schema.Struct({
|
|
37
39
|
// Same across all websocket connections
|
|
38
40
|
storeId: Schema.String,
|
|
39
41
|
// Different for each websocket connection
|
|
40
|
-
payload: Schema.optional(Schema.
|
|
41
|
-
pullRequestIds: Schema.Array(Schema.String),
|
|
42
|
+
payload: Schema.optional(Schema.Json),
|
|
43
|
+
pullRequestIds: Schema.Array(Schema.Union([Schema.String, Schema.Finite])),
|
|
42
44
|
// Headers forwarded from the initial request (via forwardHeaders option)
|
|
43
|
-
headers: Schema.optional(Schema.Record(
|
|
45
|
+
headers: Schema.optional(Schema.Record(Schema.String, Schema.String)),
|
|
44
46
|
}));
|
|
45
47
|
/** Helper to extract headers from a request based on the forwardHeaders option */
|
|
46
48
|
export const extractForwardedHeaders = (request, forwardHeaders) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/cf-worker/shared.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/cf-worker/shared.ts"],"names":[],"mappings":"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"}
|