@livestore/sync-cf 0.4.0-dev.2 → 0.4.0-dev.20
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 +60 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/cf-worker/do/durable-object.d.ts +45 -0
- package/dist/cf-worker/do/durable-object.d.ts.map +1 -0
- package/dist/cf-worker/do/durable-object.js +151 -0
- package/dist/cf-worker/do/durable-object.js.map +1 -0
- package/dist/cf-worker/do/layer.d.ts +34 -0
- package/dist/cf-worker/do/layer.d.ts.map +1 -0
- package/dist/cf-worker/do/layer.js +91 -0
- package/dist/cf-worker/do/layer.js.map +1 -0
- package/dist/cf-worker/do/pull.d.ts +6 -0
- package/dist/cf-worker/do/pull.d.ts.map +1 -0
- package/dist/cf-worker/do/pull.js +47 -0
- package/dist/cf-worker/do/pull.js.map +1 -0
- package/dist/cf-worker/do/push.d.ts +14 -0
- package/dist/cf-worker/do/push.d.ts.map +1 -0
- package/dist/cf-worker/do/push.js +131 -0
- package/dist/cf-worker/do/push.js.map +1 -0
- package/dist/cf-worker/{durable-object.d.ts → do/sqlite.d.ts} +83 -67
- package/dist/cf-worker/do/sqlite.d.ts.map +1 -0
- package/dist/cf-worker/do/sqlite.js +36 -0
- package/dist/cf-worker/do/sqlite.js.map +1 -0
- package/dist/cf-worker/do/sync-storage.d.ts +25 -0
- package/dist/cf-worker/do/sync-storage.d.ts.map +1 -0
- package/dist/cf-worker/do/sync-storage.js +191 -0
- package/dist/cf-worker/do/sync-storage.js.map +1 -0
- package/dist/cf-worker/do/transport/do-rpc-server.d.ts +9 -0
- package/dist/cf-worker/do/transport/do-rpc-server.d.ts.map +1 -0
- package/dist/cf-worker/do/transport/do-rpc-server.js +45 -0
- package/dist/cf-worker/do/transport/do-rpc-server.js.map +1 -0
- package/dist/cf-worker/do/transport/http-rpc-server.d.ts +8 -0
- package/dist/cf-worker/do/transport/http-rpc-server.d.ts.map +1 -0
- package/dist/cf-worker/do/transport/http-rpc-server.js +30 -0
- package/dist/cf-worker/do/transport/http-rpc-server.js.map +1 -0
- package/dist/cf-worker/do/transport/ws-rpc-server.d.ts +4 -0
- package/dist/cf-worker/do/transport/ws-rpc-server.d.ts.map +1 -0
- package/dist/cf-worker/do/transport/ws-rpc-server.js +21 -0
- package/dist/cf-worker/do/transport/ws-rpc-server.js.map +1 -0
- package/dist/cf-worker/mod.d.ts +4 -2
- package/dist/cf-worker/mod.d.ts.map +1 -1
- package/dist/cf-worker/mod.js +3 -2
- package/dist/cf-worker/mod.js.map +1 -1
- package/dist/cf-worker/shared.d.ts +175 -0
- package/dist/cf-worker/shared.d.ts.map +1 -0
- package/dist/cf-worker/shared.js +43 -0
- package/dist/cf-worker/shared.js.map +1 -0
- package/dist/cf-worker/worker.d.ts +59 -51
- package/dist/cf-worker/worker.d.ts.map +1 -1
- package/dist/cf-worker/worker.js +75 -43
- package/dist/cf-worker/worker.js.map +1 -1
- package/dist/client/mod.d.ts +4 -0
- package/dist/client/mod.d.ts.map +1 -0
- package/dist/client/mod.js +4 -0
- package/dist/client/mod.js.map +1 -0
- package/dist/client/transport/do-rpc-client.d.ts +40 -0
- package/dist/client/transport/do-rpc-client.d.ts.map +1 -0
- package/dist/client/transport/do-rpc-client.js +115 -0
- package/dist/client/transport/do-rpc-client.js.map +1 -0
- package/dist/client/transport/http-rpc-client.d.ts +43 -0
- package/dist/client/transport/http-rpc-client.d.ts.map +1 -0
- package/dist/client/transport/http-rpc-client.js +103 -0
- package/dist/client/transport/http-rpc-client.js.map +1 -0
- package/dist/client/transport/ws-rpc-client.d.ts +46 -0
- package/dist/client/transport/ws-rpc-client.d.ts.map +1 -0
- package/dist/client/transport/ws-rpc-client.js +108 -0
- package/dist/client/transport/ws-rpc-client.js.map +1 -0
- 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 +76 -0
- package/dist/common/do-rpc-schema.d.ts.map +1 -0
- package/dist/common/do-rpc-schema.js +48 -0
- package/dist/common/do-rpc-schema.js.map +1 -0
- package/dist/common/http-rpc-schema.d.ts +58 -0
- package/dist/common/http-rpc-schema.d.ts.map +1 -0
- package/dist/common/http-rpc-schema.js +37 -0
- package/dist/common/http-rpc-schema.js.map +1 -0
- package/dist/common/mod.d.ts +8 -1
- package/dist/common/mod.d.ts.map +1 -1
- package/dist/common/mod.js +7 -1
- package/dist/common/mod.js.map +1 -1
- package/dist/common/{ws-message-types.d.ts → sync-message-types.d.ts} +119 -153
- package/dist/common/sync-message-types.d.ts.map +1 -0
- package/dist/common/sync-message-types.js +60 -0
- package/dist/common/sync-message-types.js.map +1 -0
- package/dist/common/ws-rpc-schema.d.ts +55 -0
- package/dist/common/ws-rpc-schema.d.ts.map +1 -0
- package/dist/common/ws-rpc-schema.js +32 -0
- package/dist/common/ws-rpc-schema.js.map +1 -0
- package/package.json +7 -8
- package/src/cf-worker/do/durable-object.ts +238 -0
- package/src/cf-worker/do/layer.ts +128 -0
- package/src/cf-worker/do/pull.ts +75 -0
- package/src/cf-worker/do/push.ts +205 -0
- package/src/cf-worker/do/sqlite.ts +37 -0
- package/src/cf-worker/do/sync-storage.ts +323 -0
- package/src/cf-worker/do/transport/do-rpc-server.ts +84 -0
- package/src/cf-worker/do/transport/http-rpc-server.ts +51 -0
- package/src/cf-worker/do/transport/ws-rpc-server.ts +34 -0
- package/src/cf-worker/mod.ts +4 -2
- package/src/cf-worker/shared.ts +141 -0
- package/src/cf-worker/worker.ts +138 -116
- package/src/client/mod.ts +3 -0
- package/src/client/transport/do-rpc-client.ts +189 -0
- package/src/client/transport/http-rpc-client.ts +225 -0
- package/src/client/transport/ws-rpc-client.ts +202 -0
- package/src/common/constants.ts +18 -0
- package/src/common/do-rpc-schema.ts +54 -0
- package/src/common/http-rpc-schema.ts +40 -0
- package/src/common/mod.ts +10 -1
- package/src/common/sync-message-types.ts +117 -0
- package/src/common/ws-rpc-schema.ts +36 -0
- package/dist/cf-worker/cf-types.d.ts +0 -2
- package/dist/cf-worker/cf-types.d.ts.map +0 -1
- package/dist/cf-worker/cf-types.js +0 -2
- package/dist/cf-worker/cf-types.js.map +0 -1
- package/dist/cf-worker/durable-object.d.ts.map +0 -1
- package/dist/cf-worker/durable-object.js +0 -317
- package/dist/cf-worker/durable-object.js.map +0 -1
- package/dist/common/ws-message-types.d.ts.map +0 -1
- package/dist/common/ws-message-types.js +0 -57
- package/dist/common/ws-message-types.js.map +0 -1
- package/dist/sync-impl/mod.d.ts +0 -2
- package/dist/sync-impl/mod.d.ts.map +0 -1
- package/dist/sync-impl/mod.js +0 -2
- package/dist/sync-impl/mod.js.map +0 -1
- package/dist/sync-impl/ws-impl.d.ts +0 -7
- package/dist/sync-impl/ws-impl.d.ts.map +0 -1
- package/dist/sync-impl/ws-impl.js +0 -175
- package/dist/sync-impl/ws-impl.js.map +0 -1
- package/src/cf-worker/cf-types.ts +0 -12
- package/src/cf-worker/durable-object.ts +0 -478
- package/src/common/ws-message-types.ts +0 -114
- package/src/sync-impl/mod.ts +0 -1
- package/src/sync-impl/ws-impl.ts +0 -274
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { InvalidPullError, InvalidPushError, IsOfflineError, SyncBackend, UnknownError } from '@livestore/common';
|
|
2
|
+
import { splitChunkBySize } from '@livestore/common/sync';
|
|
3
|
+
import { omit } from '@livestore/utils';
|
|
4
|
+
import { Chunk, Effect, Layer, Option, RpcClient, RpcSerialization, Schedule, Schema, Socket, Stream, SubscriptionRef, UrlParams, } from '@livestore/utils/effect';
|
|
5
|
+
import { MAX_PUSH_EVENTS_PER_REQUEST, MAX_WS_MESSAGE_BYTES } from "../../common/constants.js";
|
|
6
|
+
import { SearchParamsSchema } from "../../common/mod.js";
|
|
7
|
+
import { SyncWsRpc } from "../../common/ws-rpc-schema.js";
|
|
8
|
+
/**
|
|
9
|
+
* Creates a sync backend that uses WebSocket to communicate with the sync backend.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { makeWsSync } from '@livestore/sync-cf/client'
|
|
14
|
+
*
|
|
15
|
+
* const syncBackend = makeWsSync({ url: 'wss://sync.example.com' })
|
|
16
|
+
*/
|
|
17
|
+
export const makeWsSync = (options) => ({ storeId, payload }) => Effect.gen(function* () {
|
|
18
|
+
const urlParamsData = yield* Schema.encode(SearchParamsSchema)({
|
|
19
|
+
storeId,
|
|
20
|
+
payload,
|
|
21
|
+
transport: 'ws',
|
|
22
|
+
}).pipe(UnknownError.mapToUnknownError);
|
|
23
|
+
const urlParams = UrlParams.fromInput(urlParamsData);
|
|
24
|
+
const wsUrl = `${options.url}?${UrlParams.toString(urlParams)}`;
|
|
25
|
+
const isConnected = yield* SubscriptionRef.make(false);
|
|
26
|
+
// TODO bring this back in a cross-platform way
|
|
27
|
+
// If the browser already tells us we're offline, then we'll at least wait until the browser
|
|
28
|
+
// thinks we're online again. (We'll only know for sure once the WS conneciton is established.)
|
|
29
|
+
// while (typeof navigator !== 'undefined' && navigator.onLine === false) {
|
|
30
|
+
// yield* Effect.sleep(1000)
|
|
31
|
+
// }
|
|
32
|
+
// TODO bring this back in a cross-platform way
|
|
33
|
+
// if (navigator.onLine === false) {
|
|
34
|
+
// yield* Effect.async((cb) => self.addEventListener('online', () => cb(Effect.void)))
|
|
35
|
+
// }
|
|
36
|
+
const pingInterval = options.ping?.requestInterval ?? 10_000;
|
|
37
|
+
const ProtocolLive = RpcClient.layerProtocolSocketWithIsConnected({
|
|
38
|
+
isConnected,
|
|
39
|
+
retryTransientErrors: Schedule.fixed(1000),
|
|
40
|
+
pingSchedule: Schedule.once.pipe(Schedule.andThen(Schedule.fixed(pingInterval))),
|
|
41
|
+
url: wsUrl,
|
|
42
|
+
}).pipe(Layer.provide(Socket.layerWebSocket(wsUrl)), Layer.provide(Socket.layerWebSocketConstructorGlobal), Layer.provide(RpcSerialization.layerJson));
|
|
43
|
+
// Warning: we need to build the layer here eagerly to tie it to the scope
|
|
44
|
+
// instead of using `Effect.provide(ProtocolLive)` which would close the layer scope too early
|
|
45
|
+
const ctx = yield* Layer.build(ProtocolLive);
|
|
46
|
+
const rpcClient = yield* RpcClient.make(SyncWsRpc).pipe(Effect.provide(ctx));
|
|
47
|
+
const pingTimeout = options.ping?.requestTimeout ?? 10_000;
|
|
48
|
+
const ping = Effect.gen(function* () {
|
|
49
|
+
const pinger = yield* RpcClient.SocketPinger.pipe(Effect.provide(ctx));
|
|
50
|
+
yield* pinger.ping;
|
|
51
|
+
yield* SubscriptionRef.set(isConnected, true);
|
|
52
|
+
}).pipe(Effect.timeout(pingTimeout), Effect.catchTag('TimeoutException', () => SubscriptionRef.set(isConnected, false)), UnknownError.mapToUnknownError, Effect.withSpan('ping'));
|
|
53
|
+
const backendIdHelper = yield* SyncBackend.makeBackendIdHelper;
|
|
54
|
+
return SyncBackend.of({
|
|
55
|
+
isConnected,
|
|
56
|
+
connect: ping,
|
|
57
|
+
pull: (cursor, options) => rpcClient.SyncWsRpc.Pull({
|
|
58
|
+
storeId,
|
|
59
|
+
payload,
|
|
60
|
+
cursor: cursor.pipe(Option.map((a) => ({
|
|
61
|
+
eventSequenceNumber: a.eventSequenceNumber,
|
|
62
|
+
backendId: backendIdHelper.get().pipe(Option.getOrThrow),
|
|
63
|
+
}))),
|
|
64
|
+
live: options?.live ?? false,
|
|
65
|
+
}).pipe(Stream.tap((res) => backendIdHelper.lazySet(res.backendId)), Stream.map((res) => omit(res, ['backendId'])), Stream.mapError((cause) => cause._tag === 'RpcClientError' && Socket.isSocketError(cause.cause)
|
|
66
|
+
? new IsOfflineError({ cause: cause.cause })
|
|
67
|
+
: cause._tag === 'InvalidPullError'
|
|
68
|
+
? cause
|
|
69
|
+
: InvalidPullError.make({ cause })), Stream.withSpan('pull')),
|
|
70
|
+
push: (batch) => Effect.gen(function* () {
|
|
71
|
+
if (batch.length === 0)
|
|
72
|
+
return;
|
|
73
|
+
const encodePayload = (batch) => ({
|
|
74
|
+
storeId,
|
|
75
|
+
payload,
|
|
76
|
+
batch,
|
|
77
|
+
backendId: backendIdHelper.get(),
|
|
78
|
+
});
|
|
79
|
+
const chunksChunk = yield* Chunk.fromIterable(batch).pipe(splitChunkBySize({
|
|
80
|
+
maxItems: MAX_PUSH_EVENTS_PER_REQUEST,
|
|
81
|
+
maxBytes: MAX_WS_MESSAGE_BYTES,
|
|
82
|
+
encode: encodePayload,
|
|
83
|
+
}), Effect.mapError((cause) => new InvalidPushError({ cause: new UnknownError({ cause }) })));
|
|
84
|
+
for (const sub of chunksChunk) {
|
|
85
|
+
yield* rpcClient.SyncWsRpc.Push({
|
|
86
|
+
storeId,
|
|
87
|
+
payload,
|
|
88
|
+
batch: Chunk.toReadonlyArray(sub),
|
|
89
|
+
backendId: backendIdHelper.get(),
|
|
90
|
+
}).pipe(Effect.mapError((cause) => cause._tag === 'InvalidPushError'
|
|
91
|
+
? cause
|
|
92
|
+
: new InvalidPushError({ cause: new UnknownError({ cause }) })));
|
|
93
|
+
}
|
|
94
|
+
}).pipe(Effect.withSpan('push')),
|
|
95
|
+
ping,
|
|
96
|
+
metadata: {
|
|
97
|
+
name: '@livestore/cf-sync',
|
|
98
|
+
description: 'LiveStore sync backend implementation using Cloudflare Workers & Durable Objects',
|
|
99
|
+
protocol: 'ws',
|
|
100
|
+
url: options.url,
|
|
101
|
+
},
|
|
102
|
+
supports: {
|
|
103
|
+
pullPageInfoKnown: true,
|
|
104
|
+
pullLive: true,
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
//# sourceMappingURL=ws-rpc-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-rpc-client.js","sourceRoot":"","sources":["../../../src/client/transport/ws-rpc-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const MAX_TRANSPORT_PAYLOAD_BYTES = 900000;
|
|
2
|
+
export declare const MAX_WS_MESSAGE_BYTES = 900000;
|
|
3
|
+
export declare const MAX_DO_RPC_REQUEST_BYTES = 900000;
|
|
4
|
+
export declare const MAX_HTTP_REQUEST_BYTES = 900000;
|
|
5
|
+
export declare const MAX_PULL_EVENTS_PER_MESSAGE = 100;
|
|
6
|
+
export declare const MAX_PUSH_EVENTS_PER_REQUEST = 100;
|
|
7
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,2BAA2B,SAAU,CAAA;AAElD,eAAO,MAAM,oBAAoB,SAA8B,CAAA;AAC/D,eAAO,MAAM,wBAAwB,SAA8B,CAAA;AACnE,eAAO,MAAM,sBAAsB,SAA8B,CAAA;AAIjE,eAAO,MAAM,2BAA2B,MAAM,CAAA;AAC9C,eAAO,MAAM,2BAA2B,MAAM,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Shared transport limits for Cloudflare sync provider
|
|
2
|
+
// Keep payloads comfortably below ~1MB frame caps across Cloudflare transports.
|
|
3
|
+
// References:
|
|
4
|
+
// - Durable Objects WebSockets + hibernation best practices:
|
|
5
|
+
// https://developers.cloudflare.com/durable-objects/best-practices/websockets/
|
|
6
|
+
// - Workers platform limits (general context):
|
|
7
|
+
// https://developers.cloudflare.com/workers/platform/limits/
|
|
8
|
+
// Empirically, frames just below 1MB can fail on hibernated DO WebSockets; we use 900_000 bytes to keep a safety margin.
|
|
9
|
+
export const MAX_TRANSPORT_PAYLOAD_BYTES = 900_000;
|
|
10
|
+
export const MAX_WS_MESSAGE_BYTES = MAX_TRANSPORT_PAYLOAD_BYTES;
|
|
11
|
+
export const MAX_DO_RPC_REQUEST_BYTES = MAX_TRANSPORT_PAYLOAD_BYTES;
|
|
12
|
+
export const MAX_HTTP_REQUEST_BYTES = MAX_TRANSPORT_PAYLOAD_BYTES;
|
|
13
|
+
// Upper bound for items per message/request. Mirrors server broadcast chunking.
|
|
14
|
+
// Not Cloudflare-enforced; chosen to balance payload size and latency.
|
|
15
|
+
export const MAX_PULL_EVENTS_PER_MESSAGE = 100;
|
|
16
|
+
export const MAX_PUSH_EVENTS_PER_REQUEST = 100;
|
|
17
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,gFAAgF;AAChF,cAAc;AACd,6DAA6D;AAC7D,iFAAiF;AACjF,+CAA+C;AAC/C,+DAA+D;AAC/D,yHAAyH;AACzH,MAAM,CAAC,MAAM,2BAA2B,GAAG,OAAO,CAAA;AAElD,MAAM,CAAC,MAAM,oBAAoB,GAAG,2BAA2B,CAAA;AAC/D,MAAM,CAAC,MAAM,wBAAwB,GAAG,2BAA2B,CAAA;AACnE,MAAM,CAAC,MAAM,sBAAsB,GAAG,2BAA2B,CAAA;AAEjE,gFAAgF;AAChF,uEAAuE;AACvE,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAA;AAC9C,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAA"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { InvalidPullError, InvalidPushError } from '@livestore/common';
|
|
2
|
+
import { Rpc, RpcGroup, Schema } from '@livestore/utils/effect';
|
|
3
|
+
declare const SyncDoRpc_base: RpcGroup.RpcGroup<Rpc.Rpc<"SyncDoRpc.Pull", Schema.Struct<{
|
|
4
|
+
/**
|
|
5
|
+
* While the storeId is already implied by the durable object, we still need the explicit storeId
|
|
6
|
+
* since a DO doesn't know its own id.name value. 🫠
|
|
7
|
+
* https://community.cloudflare.com/t/how-can-i-get-the-name-of-a-durable-object-from-itself/505961/8
|
|
8
|
+
*/
|
|
9
|
+
storeId: typeof Schema.String;
|
|
10
|
+
/** Needed for various reasons (e.g. auth) */
|
|
11
|
+
payload: Schema.optional<Schema.Schema<Schema.JsonValue, Schema.JsonValue, never>>;
|
|
12
|
+
/** Omitting the cursor will start from the beginning */
|
|
13
|
+
cursor: Schema.Option<Schema.Struct<{
|
|
14
|
+
backendId: Schema.SchemaClass<string, string, never>;
|
|
15
|
+
eventSequenceNumber: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">, number, never>;
|
|
16
|
+
}>>;
|
|
17
|
+
/** Whether to keep the pull stream alive and wait for more events */
|
|
18
|
+
rpcContext: Schema.optional<Schema.Struct<{
|
|
19
|
+
callerContext: Schema.Struct<{
|
|
20
|
+
bindingName: typeof Schema.String;
|
|
21
|
+
durableObjectId: typeof Schema.String;
|
|
22
|
+
}>;
|
|
23
|
+
}>>;
|
|
24
|
+
}>, import("@effect/rpc/RpcSchema").Stream<Schema.Struct<{
|
|
25
|
+
batch: Schema.Array$<Schema.Struct<{
|
|
26
|
+
eventEncoded: Schema.Struct<{
|
|
27
|
+
name: typeof Schema.String;
|
|
28
|
+
args: typeof Schema.Any;
|
|
29
|
+
seqNum: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">, number, never>;
|
|
30
|
+
parentSeqNum: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">, number, never>;
|
|
31
|
+
clientId: typeof Schema.String;
|
|
32
|
+
sessionId: typeof Schema.String;
|
|
33
|
+
}>;
|
|
34
|
+
metadata: Schema.Option<Schema.Struct<{
|
|
35
|
+
_tag: Schema.tag<"SyncMessage.SyncMetadata">;
|
|
36
|
+
} & {
|
|
37
|
+
createdAt: typeof Schema.String;
|
|
38
|
+
}>>;
|
|
39
|
+
}>>;
|
|
40
|
+
pageInfo: Schema.Union<[Schema.TaggedStruct<"MoreUnknown", {}>, Schema.TaggedStruct<"MoreKnown", {
|
|
41
|
+
remaining: typeof Schema.Number;
|
|
42
|
+
}>, Schema.TaggedStruct<"NoMore", {}>]>;
|
|
43
|
+
backendId: Schema.SchemaClass<string, string, never>;
|
|
44
|
+
rpcRequestId: typeof Schema.String;
|
|
45
|
+
}>, typeof InvalidPullError>, typeof Schema.Never, never> | Rpc.Rpc<"SyncDoRpc.Push", Schema.Struct<{
|
|
46
|
+
/**
|
|
47
|
+
* While the storeId is already implied by the durable object, we still need the explicit storeId
|
|
48
|
+
* since a DO doesn't know its own id.name value. 🫠
|
|
49
|
+
* https://community.cloudflare.com/t/how-can-i-get-the-name-of-a-durable-object-from-itself/505961/8
|
|
50
|
+
*/
|
|
51
|
+
storeId: typeof Schema.String;
|
|
52
|
+
/** Needed for various reasons (e.g. auth) */
|
|
53
|
+
payload: Schema.optional<Schema.Schema<Schema.JsonValue, Schema.JsonValue, never>>;
|
|
54
|
+
batch: Schema.Array$<Schema.Struct<{
|
|
55
|
+
name: typeof Schema.String;
|
|
56
|
+
args: typeof Schema.Any;
|
|
57
|
+
seqNum: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">, number, never>;
|
|
58
|
+
parentSeqNum: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">, number, never>;
|
|
59
|
+
clientId: typeof Schema.String;
|
|
60
|
+
sessionId: typeof Schema.String;
|
|
61
|
+
}>>;
|
|
62
|
+
backendId: Schema.Option<Schema.SchemaClass<string, string, never>>;
|
|
63
|
+
}>, Schema.Struct<{}>, typeof InvalidPushError, never> | Rpc.Rpc<"SyncDoRpc.Ping", Schema.Struct<{
|
|
64
|
+
/**
|
|
65
|
+
* While the storeId is already implied by the durable object, we still need the explicit storeId
|
|
66
|
+
* since a DO doesn't know its own id.name value. 🫠
|
|
67
|
+
* https://community.cloudflare.com/t/how-can-i-get-the-name-of-a-durable-object-from-itself/505961/8
|
|
68
|
+
*/
|
|
69
|
+
storeId: typeof Schema.String;
|
|
70
|
+
/** Needed for various reasons (e.g. auth) */
|
|
71
|
+
payload: Schema.optional<Schema.Schema<Schema.JsonValue, Schema.JsonValue, never>>;
|
|
72
|
+
}>, typeof Schema.Void, typeof Schema.Never, never>>;
|
|
73
|
+
export declare class SyncDoRpc extends SyncDoRpc_base {
|
|
74
|
+
}
|
|
75
|
+
export {};
|
|
76
|
+
//# sourceMappingURL=do-rpc-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"do-rpc-schema.d.ts","sourceRoot":"","sources":["../../src/common/do-rpc-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACtE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;;IAI7D;;;;OAIG;;IAEH,6CAA6C;;IAOzC,wDAAwD;;;;;IAGxD,qEAAqE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAhBzE;;;;OAIG;;IAEH,6CAA6C;;;;;;;;;;;;IAN7C;;;;OAIG;;IAEH,6CAA6C;;;AAI/C,qBAAa,SAAU,SAAQ,cAsC9B;CAAG"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { InvalidPullError, InvalidPushError } from '@livestore/common';
|
|
2
|
+
import { Rpc, RpcGroup, Schema } from '@livestore/utils/effect';
|
|
3
|
+
import * as SyncMessage from "./sync-message-types.js";
|
|
4
|
+
const commonPayloadFields = {
|
|
5
|
+
/**
|
|
6
|
+
* While the storeId is already implied by the durable object, we still need the explicit storeId
|
|
7
|
+
* since a DO doesn't know its own id.name value. 🫠
|
|
8
|
+
* https://community.cloudflare.com/t/how-can-i-get-the-name-of-a-durable-object-from-itself/505961/8
|
|
9
|
+
*/
|
|
10
|
+
storeId: Schema.String,
|
|
11
|
+
/** Needed for various reasons (e.g. auth) */
|
|
12
|
+
payload: Schema.optional(Schema.JsonValue),
|
|
13
|
+
};
|
|
14
|
+
export class SyncDoRpc extends RpcGroup.make(Rpc.make('SyncDoRpc.Pull', {
|
|
15
|
+
payload: {
|
|
16
|
+
/** Omitting the cursor will start from the beginning */
|
|
17
|
+
cursor: SyncMessage.PullRequest.fields.cursor,
|
|
18
|
+
// TODO rename
|
|
19
|
+
/** Whether to keep the pull stream alive and wait for more events */
|
|
20
|
+
rpcContext: Schema.optional(Schema.Struct({
|
|
21
|
+
callerContext: Schema.Struct({
|
|
22
|
+
bindingName: Schema.String,
|
|
23
|
+
durableObjectId: Schema.String,
|
|
24
|
+
}),
|
|
25
|
+
})),
|
|
26
|
+
...commonPayloadFields,
|
|
27
|
+
},
|
|
28
|
+
success: Schema.Struct({
|
|
29
|
+
rpcRequestId: Schema.String,
|
|
30
|
+
...SyncMessage.PullResponse.fields,
|
|
31
|
+
}),
|
|
32
|
+
error: InvalidPullError,
|
|
33
|
+
stream: true,
|
|
34
|
+
}), Rpc.make('SyncDoRpc.Push', {
|
|
35
|
+
payload: {
|
|
36
|
+
...SyncMessage.PushRequest.fields,
|
|
37
|
+
...commonPayloadFields,
|
|
38
|
+
},
|
|
39
|
+
success: SyncMessage.PushAck,
|
|
40
|
+
error: InvalidPushError,
|
|
41
|
+
}), Rpc.make('SyncDoRpc.Ping', {
|
|
42
|
+
payload: {
|
|
43
|
+
...commonPayloadFields,
|
|
44
|
+
},
|
|
45
|
+
success: Schema.Void,
|
|
46
|
+
})) {
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=do-rpc-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"do-rpc-schema.js","sourceRoot":"","sources":["../../src/common/do-rpc-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACtE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAA;AAEtD,MAAM,mBAAmB,GAAG;IAC1B;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC;CAC3C,CAAA;AAED,MAAM,OAAO,SAAU,SAAQ,QAAQ,CAAC,IAAI,CAC1C,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE;IACzB,OAAO,EAAE;QACP,wDAAwD;QACxD,MAAM,EAAE,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM;QAC7C,cAAc;QACd,qEAAqE;QACrE,UAAU,EAAE,MAAM,CAAC,QAAQ,CACzB,MAAM,CAAC,MAAM,CAAC;YACZ,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC;gBAC3B,WAAW,EAAE,MAAM,CAAC,MAAM;gBAC1B,eAAe,EAAE,MAAM,CAAC,MAAM;aAC/B,CAAC;SACH,CAAC,CACH;QACD,GAAG,mBAAmB;KACvB;IACD,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC,MAAM;QAC3B,GAAG,WAAW,CAAC,YAAY,CAAC,MAAM;KACnC,CAAC;IACF,KAAK,EAAE,gBAAgB;IACvB,MAAM,EAAE,IAAI;CACb,CAAC,EACF,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE;IACzB,OAAO,EAAE;QACP,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM;QACjC,GAAG,mBAAmB;KACvB;IACD,OAAO,EAAE,WAAW,CAAC,OAAO;IAC5B,KAAK,EAAE,gBAAgB;CACxB,CAAC,EACF,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE;IACzB,OAAO,EAAE;QACP,GAAG,mBAAmB;KACvB;IACD,OAAO,EAAE,MAAM,CAAC,IAAI;CACrB,CAAC,CACH;CAAG"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { InvalidPullError, InvalidPushError, UnknownError } from '@livestore/common';
|
|
2
|
+
import { Rpc, RpcGroup, Schema } from '@livestore/utils/effect';
|
|
3
|
+
declare const SyncHttpRpc_base: RpcGroup.RpcGroup<Rpc.Rpc<"SyncHttpRpc.Pull", Schema.Struct<{
|
|
4
|
+
cursor: Schema.Option<Schema.Struct<{
|
|
5
|
+
backendId: Schema.SchemaClass<string, string, never>;
|
|
6
|
+
eventSequenceNumber: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">, number, never>;
|
|
7
|
+
}>>;
|
|
8
|
+
storeId: typeof Schema.String;
|
|
9
|
+
payload: Schema.optional<Schema.Schema<Schema.JsonValue, Schema.JsonValue, never>>;
|
|
10
|
+
}>, import("@effect/rpc/RpcSchema").Stream<Schema.Struct<{
|
|
11
|
+
batch: Schema.Array$<Schema.Struct<{
|
|
12
|
+
eventEncoded: Schema.Struct<{
|
|
13
|
+
name: typeof Schema.String;
|
|
14
|
+
args: typeof Schema.Any;
|
|
15
|
+
seqNum: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">, number, never>;
|
|
16
|
+
parentSeqNum: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">, number, never>;
|
|
17
|
+
clientId: typeof Schema.String;
|
|
18
|
+
sessionId: typeof Schema.String;
|
|
19
|
+
}>;
|
|
20
|
+
metadata: Schema.Option<Schema.Struct<{
|
|
21
|
+
_tag: Schema.tag<"SyncMessage.SyncMetadata">;
|
|
22
|
+
} & {
|
|
23
|
+
createdAt: typeof Schema.String;
|
|
24
|
+
}>>;
|
|
25
|
+
}>>;
|
|
26
|
+
pageInfo: Schema.Union<[Schema.TaggedStruct<"MoreUnknown", {}>, Schema.TaggedStruct<"MoreKnown", {
|
|
27
|
+
remaining: typeof Schema.Number;
|
|
28
|
+
}>, Schema.TaggedStruct<"NoMore", {}>]>;
|
|
29
|
+
backendId: Schema.SchemaClass<string, string, never>;
|
|
30
|
+
}>, typeof InvalidPullError>, typeof Schema.Never, never> | Rpc.Rpc<"SyncHttpRpc.Push", Schema.Struct<{
|
|
31
|
+
batch: Schema.Array$<Schema.Struct<{
|
|
32
|
+
name: typeof Schema.String;
|
|
33
|
+
args: typeof Schema.Any;
|
|
34
|
+
seqNum: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">, number, never>;
|
|
35
|
+
parentSeqNum: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">, number, never>;
|
|
36
|
+
clientId: typeof Schema.String;
|
|
37
|
+
sessionId: typeof Schema.String;
|
|
38
|
+
}>>;
|
|
39
|
+
backendId: Schema.Option<Schema.SchemaClass<string, string, never>>;
|
|
40
|
+
storeId: typeof Schema.String;
|
|
41
|
+
payload: Schema.optional<Schema.Schema<Schema.JsonValue, Schema.JsonValue, never>>;
|
|
42
|
+
}>, Schema.Struct<{}>, typeof InvalidPushError, never> | Rpc.Rpc<"SyncHttpRpc.Ping", Schema.Struct<{
|
|
43
|
+
storeId: typeof Schema.String;
|
|
44
|
+
payload: Schema.optional<Schema.Schema<Schema.JsonValue, Schema.JsonValue, never>>;
|
|
45
|
+
}>, Schema.Struct<{
|
|
46
|
+
_tag: Schema.tag<"SyncMessage.Pong">;
|
|
47
|
+
}>, typeof UnknownError, never>>;
|
|
48
|
+
/**
|
|
49
|
+
* HTTP RPC Schema for LiveStore CF Sync Provider
|
|
50
|
+
*
|
|
51
|
+
* This defines the RPC endpoints available over HTTP transport.
|
|
52
|
+
* Unlike WebSocket transport which maintains persistent connections,
|
|
53
|
+
* HTTP transport uses request/response patterns for each operation.
|
|
54
|
+
*/
|
|
55
|
+
export declare class SyncHttpRpc extends SyncHttpRpc_base {
|
|
56
|
+
}
|
|
57
|
+
export {};
|
|
58
|
+
//# sourceMappingURL=http-rpc-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-rpc-schema.d.ts","sourceRoot":"","sources":["../../src/common/http-rpc-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACpF,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAG/D;;;;;;GAMG;AACH,qBAAa,WAAY,SAAQ,gBA4BhC;CAAG"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { InvalidPullError, InvalidPushError, UnknownError } from '@livestore/common';
|
|
2
|
+
import { Rpc, RpcGroup, Schema } from '@livestore/utils/effect';
|
|
3
|
+
import * as SyncMessage from "./sync-message-types.js";
|
|
4
|
+
/**
|
|
5
|
+
* HTTP RPC Schema for LiveStore CF Sync Provider
|
|
6
|
+
*
|
|
7
|
+
* This defines the RPC endpoints available over HTTP transport.
|
|
8
|
+
* Unlike WebSocket transport which maintains persistent connections,
|
|
9
|
+
* HTTP transport uses request/response patterns for each operation.
|
|
10
|
+
*/
|
|
11
|
+
export class SyncHttpRpc extends RpcGroup.make(Rpc.make('SyncHttpRpc.Pull', {
|
|
12
|
+
payload: Schema.Struct({
|
|
13
|
+
storeId: Schema.String,
|
|
14
|
+
payload: Schema.optional(Schema.JsonValue),
|
|
15
|
+
...SyncMessage.PullRequest.fields,
|
|
16
|
+
}),
|
|
17
|
+
success: SyncMessage.PullResponse,
|
|
18
|
+
error: InvalidPullError,
|
|
19
|
+
stream: true,
|
|
20
|
+
}), Rpc.make('SyncHttpRpc.Push', {
|
|
21
|
+
payload: Schema.Struct({
|
|
22
|
+
storeId: Schema.String,
|
|
23
|
+
payload: Schema.optional(Schema.JsonValue),
|
|
24
|
+
...SyncMessage.PushRequest.fields,
|
|
25
|
+
}),
|
|
26
|
+
success: SyncMessage.PushAck,
|
|
27
|
+
error: InvalidPushError,
|
|
28
|
+
}), Rpc.make('SyncHttpRpc.Ping', {
|
|
29
|
+
payload: Schema.Struct({
|
|
30
|
+
storeId: Schema.String,
|
|
31
|
+
payload: Schema.optional(Schema.JsonValue),
|
|
32
|
+
}),
|
|
33
|
+
success: SyncMessage.Pong,
|
|
34
|
+
error: UnknownError,
|
|
35
|
+
})) {
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=http-rpc-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-rpc-schema.js","sourceRoot":"","sources":["../../src/common/http-rpc-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACpF,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAA;AAEtD;;;;;;GAMG;AACH,MAAM,OAAO,WAAY,SAAQ,QAAQ,CAAC,IAAI,CAC5C,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE;IAC3B,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,YAAY;IACjC,KAAK,EAAE,gBAAgB;IACvB,MAAM,EAAE,IAAI;CACb,CAAC,EACF,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE;IAC3B,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,gBAAgB;CACxB,CAAC,EACF,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE;IAC3B,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC,MAAM;QACtB,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC;KAC3C,CAAC;IACF,OAAO,EAAE,WAAW,CAAC,IAAI;IACzB,KAAK,EAAE,YAAY;CACpB,CAAC,CACH;CAAG"}
|
package/dist/common/mod.d.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
import { OversizeChunkItemError, splitChunkBySize } from '@livestore/common/sync';
|
|
1
2
|
import { Schema } from '@livestore/utils/effect';
|
|
2
|
-
export
|
|
3
|
+
export type { CfTypes } from '@livestore/common-cf';
|
|
4
|
+
export * from './constants.ts';
|
|
5
|
+
export { SyncHttpRpc } from './http-rpc-schema.ts';
|
|
6
|
+
export * as SyncMessage from './sync-message-types.ts';
|
|
7
|
+
export { OversizeChunkItemError, splitChunkBySize };
|
|
3
8
|
export declare const SearchParamsSchema: Schema.Struct<{
|
|
4
9
|
storeId: typeof Schema.String;
|
|
5
10
|
payload: Schema.UndefinedOr<Schema.transform<Schema.transformOrFail<Schema.SchemaClass<string, string, never>, typeof Schema.String, never>, Schema.transform<Schema.SchemaClass<unknown, string, never>, Schema.Schema<Schema.JsonValue, Schema.JsonValue, never>>>>;
|
|
11
|
+
transport: Schema.Literal<["http", "ws"]>;
|
|
6
12
|
}>;
|
|
13
|
+
export type SearchParams = typeof SearchParamsSchema.Type;
|
|
7
14
|
//# sourceMappingURL=mod.d.ts.map
|
package/dist/common/mod.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/common/mod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEhD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/common/mod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACjF,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEhD,YAAY,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACnD,cAAc,gBAAgB,CAAA;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAA;AACtD,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,CAAA;AAEnD,eAAO,MAAM,kBAAkB;;;;EAK7B,CAAA;AAEF,MAAM,MAAM,YAAY,GAAG,OAAO,kBAAkB,CAAC,IAAI,CAAA"}
|
package/dist/common/mod.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
import { OversizeChunkItemError, splitChunkBySize } from '@livestore/common/sync';
|
|
1
2
|
import { Schema } from '@livestore/utils/effect';
|
|
2
|
-
export *
|
|
3
|
+
export * from "./constants.js";
|
|
4
|
+
export { SyncHttpRpc } from "./http-rpc-schema.js";
|
|
5
|
+
export * as SyncMessage from "./sync-message-types.js";
|
|
6
|
+
export { OversizeChunkItemError, splitChunkBySize };
|
|
3
7
|
export const SearchParamsSchema = Schema.Struct({
|
|
4
8
|
storeId: Schema.String,
|
|
5
9
|
payload: Schema.compose(Schema.StringFromUriComponent, Schema.parseJson(Schema.JsonValue)).pipe(Schema.UndefinedOr),
|
|
10
|
+
// NOTE `do-rpc` is handled differently
|
|
11
|
+
transport: Schema.Literal('http', 'ws'),
|
|
6
12
|
});
|
|
7
13
|
//# sourceMappingURL=mod.js.map
|
package/dist/common/mod.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/common/mod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/common/mod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACjF,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAGhD,cAAc,gBAAgB,CAAA;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAA;AACtD,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,CAAA;AAEnD,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC9C,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,sBAAsB,EAAE,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;IACnH,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC;CACxC,CAAC,CAAA"}
|