@livestore/sync-cf 0.3.0-dev.2 → 0.3.0-dev.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/cf-worker/durable-object.d.ts +42 -37
- package/dist/cf-worker/durable-object.d.ts.map +1 -1
- package/dist/cf-worker/durable-object.js +224 -152
- package/dist/cf-worker/durable-object.js.map +1 -1
- package/dist/cf-worker/mod.d.ts +3 -0
- package/dist/cf-worker/mod.d.ts.map +1 -0
- package/dist/cf-worker/mod.js +3 -0
- package/dist/cf-worker/mod.js.map +1 -0
- package/dist/cf-worker/worker.d.ts +6 -0
- package/dist/cf-worker/worker.d.ts.map +1 -0
- package/dist/cf-worker/worker.js +29 -0
- package/dist/cf-worker/worker.js.map +1 -0
- package/dist/common/{index.js → mod.d.ts} +1 -1
- package/dist/common/mod.d.ts.map +1 -0
- package/dist/common/{index.d.ts → mod.js} +1 -1
- package/dist/common/mod.js.map +1 -0
- package/dist/common/ws-message-types.d.ts +58 -233
- package/dist/common/ws-message-types.d.ts.map +1 -1
- package/dist/common/ws-message-types.js +6 -11
- package/dist/common/ws-message-types.js.map +1 -1
- package/dist/sync-impl/mod.d.ts +2 -0
- package/dist/sync-impl/mod.d.ts.map +1 -0
- package/dist/sync-impl/mod.js +2 -0
- package/dist/sync-impl/mod.js.map +1 -0
- package/dist/sync-impl/ws-impl.d.ts +3 -12
- package/dist/sync-impl/ws-impl.d.ts.map +1 -1
- package/dist/sync-impl/ws-impl.js +73 -28
- package/dist/sync-impl/ws-impl.js.map +1 -1
- package/package.json +15 -13
- package/src/cf-worker/durable-object.ts +299 -172
- package/src/cf-worker/mod.ts +2 -0
- package/src/cf-worker/worker.ts +39 -0
- package/src/common/ws-message-types.ts +7 -22
- package/src/sync-impl/ws-impl.ts +85 -47
- package/dist/cf-worker/index.d.ts +0 -8
- package/dist/cf-worker/index.d.ts.map +0 -1
- package/dist/cf-worker/index.js +0 -67
- package/dist/cf-worker/index.js.map +0 -1
- package/dist/common/index.d.ts.map +0 -1
- package/dist/common/index.js.map +0 -1
- package/dist/sync-impl/index.d.ts +0 -2
- package/dist/sync-impl/index.d.ts.map +0 -1
- package/dist/sync-impl/index.js +0 -2
- package/dist/sync-impl/index.js.map +0 -1
- package/src/cf-worker/index.ts +0 -84
- /package/src/common/{index.ts → mod.ts} +0 -0
- /package/src/sync-impl/{index.ts → mod.ts} +0 -0
|
@@ -17,35 +17,27 @@ export const SyncMetadata = Schema.Struct({
|
|
|
17
17
|
export type SyncMetadata = typeof SyncMetadata.Type
|
|
18
18
|
|
|
19
19
|
export const PullRes = Schema.TaggedStruct('WSMessage.PullRes', {
|
|
20
|
-
|
|
21
|
-
events: Schema.Array(
|
|
20
|
+
batch: Schema.Array(
|
|
22
21
|
Schema.Struct({
|
|
23
|
-
mutationEventEncoded: MutationEvent.
|
|
22
|
+
mutationEventEncoded: MutationEvent.AnyEncodedGlobal,
|
|
24
23
|
metadata: Schema.Option(SyncMetadata),
|
|
25
24
|
}),
|
|
26
25
|
),
|
|
26
|
+
requestId: Schema.Struct({ context: Schema.Literal('pull', 'push'), requestId: Schema.String }),
|
|
27
27
|
remaining: Schema.Number,
|
|
28
28
|
})
|
|
29
29
|
|
|
30
30
|
export type PullRes = typeof PullRes.Type
|
|
31
31
|
|
|
32
|
-
export const PushBroadcast = Schema.TaggedStruct('WSMessage.PushBroadcast', {
|
|
33
|
-
mutationEventEncoded: MutationEvent.EncodedAny,
|
|
34
|
-
metadata: Schema.Option(SyncMetadata),
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
export type PushBroadcast = typeof PushBroadcast.Type
|
|
38
|
-
|
|
39
32
|
export const PushReq = Schema.TaggedStruct('WSMessage.PushReq', {
|
|
40
33
|
requestId: Schema.String,
|
|
41
|
-
batch: Schema.Array(MutationEvent.
|
|
34
|
+
batch: Schema.Array(MutationEvent.AnyEncodedGlobal),
|
|
42
35
|
})
|
|
43
36
|
|
|
44
37
|
export type PushReq = typeof PushReq.Type
|
|
45
38
|
|
|
46
39
|
export const PushAck = Schema.TaggedStruct('WSMessage.PushAck', {
|
|
47
40
|
requestId: Schema.String,
|
|
48
|
-
mutationId: Schema.Number,
|
|
49
41
|
})
|
|
50
42
|
|
|
51
43
|
export type PushAck = typeof PushAck.Type
|
|
@@ -55,6 +47,8 @@ export const Error = Schema.TaggedStruct('WSMessage.Error', {
|
|
|
55
47
|
message: Schema.String,
|
|
56
48
|
})
|
|
57
49
|
|
|
50
|
+
export type Error = typeof Error.Type
|
|
51
|
+
|
|
58
52
|
export const Ping = Schema.TaggedStruct('WSMessage.Ping', {
|
|
59
53
|
requestId: Schema.Literal('ping'),
|
|
60
54
|
})
|
|
@@ -99,7 +93,6 @@ export type AdminInfoRes = typeof AdminInfoRes.Type
|
|
|
99
93
|
export const Message = Schema.Union(
|
|
100
94
|
PullReq,
|
|
101
95
|
PullRes,
|
|
102
|
-
PushBroadcast,
|
|
103
96
|
PushReq,
|
|
104
97
|
PushAck,
|
|
105
98
|
Error,
|
|
@@ -113,15 +106,7 @@ export const Message = Schema.Union(
|
|
|
113
106
|
export type Message = typeof Message.Type
|
|
114
107
|
export type MessageEncoded = typeof Message.Encoded
|
|
115
108
|
|
|
116
|
-
export const BackendToClientMessage = Schema.Union(
|
|
117
|
-
PullRes,
|
|
118
|
-
PushBroadcast,
|
|
119
|
-
PushAck,
|
|
120
|
-
AdminResetRoomRes,
|
|
121
|
-
AdminInfoRes,
|
|
122
|
-
Error,
|
|
123
|
-
Pong,
|
|
124
|
-
)
|
|
109
|
+
export const BackendToClientMessage = Schema.Union(PullRes, PushAck, AdminResetRoomRes, AdminInfoRes, Error, Pong)
|
|
125
110
|
export type BackendToClientMessage = typeof BackendToClientMessage.Type
|
|
126
111
|
|
|
127
112
|
export const ClientToBackendMessage = Schema.Union(PullReq, PushReq, AdminResetRoomReq, AdminInfoReq, Ping)
|
package/src/sync-impl/ws-impl.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/// <reference lib="dom" />
|
|
2
2
|
|
|
3
|
-
import type { SyncBackend
|
|
3
|
+
import type { SyncBackend } from '@livestore/common'
|
|
4
4
|
import { InvalidPullError, InvalidPushError } from '@livestore/common'
|
|
5
|
-
import {
|
|
5
|
+
import { EventId } from '@livestore/common/schema'
|
|
6
|
+
import { LS_DEV, shouldNeverHappen } from '@livestore/utils'
|
|
6
7
|
import type { Scope } from '@livestore/utils/effect'
|
|
7
8
|
import {
|
|
8
9
|
Deferred,
|
|
@@ -18,57 +19,92 @@ import {
|
|
|
18
19
|
} from '@livestore/utils/effect'
|
|
19
20
|
import { nanoid } from '@livestore/utils/nanoid'
|
|
20
21
|
|
|
21
|
-
import { WSMessage } from '../common/
|
|
22
|
+
import { WSMessage } from '../common/mod.js'
|
|
22
23
|
import type { SyncMetadata } from '../common/ws-message-types.js'
|
|
23
24
|
|
|
24
|
-
export interface WsSyncOptions
|
|
25
|
-
type: 'cf'
|
|
25
|
+
export interface WsSyncOptions {
|
|
26
26
|
url: string
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
interface LiveStoreGlobalCf {
|
|
31
|
-
syncBackend: WsSyncOptions
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
declare global {
|
|
35
|
-
interface LiveStoreGlobal extends LiveStoreGlobalCf {}
|
|
27
|
+
storeId: string
|
|
36
28
|
}
|
|
37
29
|
|
|
38
30
|
export const makeWsSync = (options: WsSyncOptions): Effect.Effect<SyncBackend<SyncMetadata>, never, Scope.Scope> =>
|
|
39
31
|
Effect.gen(function* () {
|
|
40
|
-
|
|
32
|
+
// TODO also allow for auth scenarios
|
|
33
|
+
const wsUrl = `${options.url}/websocket?storeId=${options.storeId}`
|
|
41
34
|
|
|
42
35
|
const { isConnected, incomingMessages, send } = yield* connect(wsUrl)
|
|
43
36
|
|
|
37
|
+
/**
|
|
38
|
+
* We need to account for the scenario where push-caused PullRes message arrive before the pull-caused PullRes message.
|
|
39
|
+
* i.e. a scenario where the WS connection is created but before the server processed the initial pull, a push from
|
|
40
|
+
* another client triggers a PullRes message sent to this client which we need to stash until our pull-caused
|
|
41
|
+
* PullRes message arrives at which point we can combine the stashed events with the pull-caused events and continue.
|
|
42
|
+
*/
|
|
43
|
+
const stashedPullBatch: WSMessage.PullRes['batch'][number][] = []
|
|
44
|
+
|
|
45
|
+
// We currently only support one pull stream for a sync backend.
|
|
46
|
+
let pullStarted = false
|
|
47
|
+
|
|
44
48
|
const api = {
|
|
45
49
|
isConnected,
|
|
46
50
|
pull: (args) =>
|
|
47
51
|
Effect.gen(function* () {
|
|
52
|
+
if (pullStarted) {
|
|
53
|
+
return shouldNeverHappen(`Pull already started for this sync backend.`)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
pullStarted = true
|
|
57
|
+
|
|
58
|
+
let pullResponseReceived = false
|
|
59
|
+
|
|
48
60
|
const requestId = nanoid()
|
|
49
61
|
const cursor = Option.getOrUndefined(args)?.cursor.global
|
|
50
62
|
|
|
51
63
|
yield* send(WSMessage.PullReq.make({ cursor, requestId }))
|
|
52
64
|
|
|
53
65
|
return Stream.fromPubSub(incomingMessages).pipe(
|
|
54
|
-
Stream.filter((_) => (_._tag === 'WSMessage.PullRes' ? _.requestId === requestId : true)),
|
|
55
66
|
Stream.tap((_) =>
|
|
56
67
|
_._tag === 'WSMessage.Error' && _.requestId === requestId
|
|
57
68
|
? new InvalidPullError({ message: _.message })
|
|
58
69
|
: Effect.void,
|
|
59
70
|
),
|
|
60
|
-
Stream.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
71
|
+
Stream.filterMap((msg) => {
|
|
72
|
+
if (msg._tag === 'WSMessage.PullRes') {
|
|
73
|
+
if (msg.requestId.context === 'pull') {
|
|
74
|
+
if (msg.requestId.requestId === requestId) {
|
|
75
|
+
pullResponseReceived = true
|
|
76
|
+
|
|
77
|
+
if (stashedPullBatch.length > 0 && msg.remaining === 0) {
|
|
78
|
+
const pullResHead = msg.batch.at(-1)?.mutationEventEncoded.id ?? EventId.ROOT.global
|
|
79
|
+
// Index where stashed events are greater than pullResHead
|
|
80
|
+
const newPartialBatchIndex = stashedPullBatch.findIndex(
|
|
81
|
+
(batchItem) => batchItem.mutationEventEncoded.id > pullResHead,
|
|
82
|
+
)
|
|
83
|
+
const batchWithNewStashedEvents =
|
|
84
|
+
newPartialBatchIndex === -1 ? [] : stashedPullBatch.slice(newPartialBatchIndex)
|
|
85
|
+
const combinedBatch = [...msg.batch, ...batchWithNewStashedEvents]
|
|
86
|
+
return Option.some({ ...msg, batch: combinedBatch, remaining: 0 })
|
|
87
|
+
} else {
|
|
88
|
+
return Option.some(msg)
|
|
89
|
+
}
|
|
90
|
+
} else {
|
|
91
|
+
// Ignore
|
|
92
|
+
return Option.none()
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
if (pullResponseReceived) {
|
|
96
|
+
return Option.some(msg)
|
|
97
|
+
} else {
|
|
98
|
+
stashedPullBatch.push(...msg.batch)
|
|
99
|
+
return Option.none()
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return Option.none()
|
|
105
|
+
}),
|
|
106
|
+
// This call is mostly here to for type narrowing
|
|
107
|
+
Stream.filter(Schema.is(WSMessage.PullRes)),
|
|
72
108
|
)
|
|
73
109
|
}).pipe(Stream.unwrap),
|
|
74
110
|
|
|
@@ -78,15 +114,12 @@ export const makeWsSync = (options: WsSyncOptions): Effect.Effect<SyncBackend<Sy
|
|
|
78
114
|
const requestId = nanoid()
|
|
79
115
|
|
|
80
116
|
yield* Stream.fromPubSub(incomingMessages).pipe(
|
|
81
|
-
Stream.filter((_) => _._tag !== 'WSMessage.PushBroadcast' && _.requestId === requestId),
|
|
82
117
|
Stream.tap((_) =>
|
|
83
|
-
_._tag === 'WSMessage.Error'
|
|
118
|
+
_._tag === 'WSMessage.Error' && _.requestId === requestId
|
|
84
119
|
? Deferred.fail(ready, new InvalidPushError({ reason: { _tag: 'Unexpected', message: _.message } }))
|
|
85
120
|
: Effect.void,
|
|
86
121
|
),
|
|
87
|
-
Stream.filter(
|
|
88
|
-
// TODO bring back filterting of "own events"
|
|
89
|
-
// Stream.filter((_) => _.mutationId === mutationEventEncoded.id.global),
|
|
122
|
+
Stream.filter((_) => _._tag === 'WSMessage.PushAck' && _.requestId === requestId),
|
|
90
123
|
Stream.take(1),
|
|
91
124
|
Stream.tap(() => Deferred.succeed(ready, void 0)),
|
|
92
125
|
Stream.runDrain,
|
|
@@ -123,21 +156,23 @@ const connect = (wsUrl: string) =>
|
|
|
123
156
|
// Wait first until we're online
|
|
124
157
|
yield* waitUntilOnline
|
|
125
158
|
|
|
126
|
-
yield* Effect.spanEvent(
|
|
127
|
-
`Sending message: ${message._tag}`,
|
|
128
|
-
message._tag === 'WSMessage.PushReq'
|
|
129
|
-
? {
|
|
130
|
-
id: message.batch[0]!.id.global,
|
|
131
|
-
parentId: message.batch[0]!.parentId.global,
|
|
132
|
-
batchLength: message.batch.length,
|
|
133
|
-
}
|
|
134
|
-
: message._tag === 'WSMessage.PullReq'
|
|
135
|
-
? { cursor: message.cursor ?? '-' }
|
|
136
|
-
: {},
|
|
137
|
-
)
|
|
138
|
-
|
|
139
159
|
// TODO use MsgPack instead of JSON to speed up the serialization / reduce the size of the messages
|
|
140
160
|
socketRef.current!.send(Schema.encodeSync(Schema.parseJson(WSMessage.Message))(message))
|
|
161
|
+
|
|
162
|
+
if (LS_DEV) {
|
|
163
|
+
yield* Effect.spanEvent(
|
|
164
|
+
`Sent message: ${message._tag}`,
|
|
165
|
+
message._tag === 'WSMessage.PushReq'
|
|
166
|
+
? {
|
|
167
|
+
id: message.batch[0]!.id,
|
|
168
|
+
parentId: message.batch[0]!.parentId,
|
|
169
|
+
batchLength: message.batch.length,
|
|
170
|
+
}
|
|
171
|
+
: message._tag === 'WSMessage.PullReq'
|
|
172
|
+
? { cursor: message.cursor ?? '-' }
|
|
173
|
+
: {},
|
|
174
|
+
)
|
|
175
|
+
}
|
|
141
176
|
})
|
|
142
177
|
|
|
143
178
|
const innerConnect = Effect.gen(function* () {
|
|
@@ -146,11 +181,13 @@ const connect = (wsUrl: string) =>
|
|
|
146
181
|
while (typeof navigator !== 'undefined' && navigator.onLine === false) {
|
|
147
182
|
yield* Effect.sleep(1000)
|
|
148
183
|
}
|
|
184
|
+
// TODO bring this back in a cross-platform way
|
|
149
185
|
// if (navigator.onLine === false) {
|
|
150
186
|
// yield* Effect.async((cb) => self.addEventListener('online', () => cb(Effect.void)))
|
|
151
187
|
// }
|
|
152
188
|
|
|
153
189
|
const socket = yield* WebSocket.makeWebSocket({ url: wsUrl, reconnect: Schedule.exponential(100) })
|
|
190
|
+
// socket.binaryType = 'arraybuffer'
|
|
154
191
|
|
|
155
192
|
yield* SubscriptionRef.set(isConnected, true)
|
|
156
193
|
socketRef.current = socket
|
|
@@ -191,7 +228,8 @@ const connect = (wsUrl: string) =>
|
|
|
191
228
|
// NOTE it seems that this callback doesn't work reliably on a worker but only via `window.addEventListener`
|
|
192
229
|
// We might need to proxy the event from the main thread to the worker if we want this to work reliably.
|
|
193
230
|
// eslint-disable-next-line unicorn/prefer-global-this
|
|
194
|
-
if (typeof self !== 'undefined') {
|
|
231
|
+
if (typeof self !== 'undefined' && typeof self.addEventListener === 'function') {
|
|
232
|
+
// TODO support an Expo equivalent for this
|
|
195
233
|
// eslint-disable-next-line unicorn/prefer-global-this
|
|
196
234
|
yield* Effect.eventListener(self, 'offline', () => Deferred.succeed(connectionClosed, void 0))
|
|
197
235
|
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/// <reference no-default-lib="true"/>
|
|
2
|
-
import type { Env } from './durable-object.js';
|
|
3
|
-
export * from './durable-object.js';
|
|
4
|
-
declare const _default: {
|
|
5
|
-
fetch: (request: Request, env: Env, _ctx: ExecutionContext) => Promise<Response>;
|
|
6
|
-
};
|
|
7
|
-
export default _default;
|
|
8
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cf-worker/index.ts"],"names":[],"mappings":";AAMA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAA;AAE9C,cAAc,qBAAqB,CAAA;;qBA4CV,OAAO,OAAO,GAAG,QAAQ,gBAAgB,KAAG,OAAO,CAAC,QAAQ,CAAC;;AADtF,wBAgCC"}
|
package/dist/cf-worker/index.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/// <reference no-default-lib="true"/>
|
|
2
|
-
/// <reference lib="esnext" />
|
|
3
|
-
export * from './durable-object.js';
|
|
4
|
-
// const handleRequest = (request: Request, env: Env) =>
|
|
5
|
-
// HttpServer.router.empty.pipe(
|
|
6
|
-
// HttpServer.router.get(
|
|
7
|
-
// '/websocket',
|
|
8
|
-
// Effect.gen(function* () {
|
|
9
|
-
// // This example will refer to the same Durable Object instance,
|
|
10
|
-
// // since the name "foo" is hardcoded.
|
|
11
|
-
// const id = env.WEBSOCKET_SERVER.idFromName('foo')
|
|
12
|
-
// const durableObject = env.WEBSOCKET_SERVER.get(id)
|
|
13
|
-
// HttpServer.
|
|
14
|
-
// // Expect to receive a WebSocket Upgrade request.
|
|
15
|
-
// // If there is one, accept the request and return a WebSocket Response.
|
|
16
|
-
// const headerRes = yield* HttpServer.request
|
|
17
|
-
// .schemaHeaders(
|
|
18
|
-
// Schema.Struct({
|
|
19
|
-
// Upgrade: Schema.Literal('websocket'),
|
|
20
|
-
// }),
|
|
21
|
-
// )
|
|
22
|
-
// .pipe(Effect.either)
|
|
23
|
-
// if (headerRes._tag === 'Left') {
|
|
24
|
-
// // return new Response('Durable Object expected Upgrade: websocket', { status: 426 })
|
|
25
|
-
// return yield* HttpServer.response.text('Durable Object expected Upgrade: websocket', { status: 426 })
|
|
26
|
-
// }
|
|
27
|
-
// HttpServer.response.empty
|
|
28
|
-
// return yield* Effect.promise(() => durableObject.fetch(request))
|
|
29
|
-
// }),
|
|
30
|
-
// ),
|
|
31
|
-
// HttpServer.router.catchAll((e) => {
|
|
32
|
-
// console.log(e)
|
|
33
|
-
// return HttpServer.response.empty({ status: 400 })
|
|
34
|
-
// }),
|
|
35
|
-
// (_) => HttpServer.app.toWebHandler(_)(request),
|
|
36
|
-
// // request
|
|
37
|
-
// )
|
|
38
|
-
// Worker
|
|
39
|
-
export default {
|
|
40
|
-
fetch: async (request, env, _ctx) => {
|
|
41
|
-
const url = new URL(request.url);
|
|
42
|
-
const searchParams = url.searchParams;
|
|
43
|
-
const roomId = searchParams.get('room');
|
|
44
|
-
if (roomId === null) {
|
|
45
|
-
return new Response('Room ID is required', { status: 400 });
|
|
46
|
-
}
|
|
47
|
-
// This example will refer to the same Durable Object instance,
|
|
48
|
-
// since the name "foo" is hardcoded.
|
|
49
|
-
const id = env.WEBSOCKET_SERVER.idFromName(roomId);
|
|
50
|
-
const durableObject = env.WEBSOCKET_SERVER.get(id);
|
|
51
|
-
if (url.pathname.endsWith('/websocket')) {
|
|
52
|
-
const upgradeHeader = request.headers.get('Upgrade');
|
|
53
|
-
if (!upgradeHeader || upgradeHeader !== 'websocket') {
|
|
54
|
-
return new Response('Durable Object expected Upgrade: websocket', { status: 426 });
|
|
55
|
-
}
|
|
56
|
-
return durableObject.fetch(request);
|
|
57
|
-
}
|
|
58
|
-
return new Response(null, {
|
|
59
|
-
status: 400,
|
|
60
|
-
statusText: 'Bad Request',
|
|
61
|
-
headers: {
|
|
62
|
-
'Content-Type': 'text/plain',
|
|
63
|
-
},
|
|
64
|
-
});
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cf-worker/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,8BAA8B;AAO9B,cAAc,qBAAqB,CAAA;AAEnC,wDAAwD;AACxD,kCAAkC;AAClC,6BAA6B;AAC7B,sBAAsB;AACtB,kCAAkC;AAClC,0EAA0E;AAC1E,gDAAgD;AAChD,4DAA4D;AAC5D,6DAA6D;AAE7D,sBAAsB;AAEtB,4DAA4D;AAC5D,kFAAkF;AAClF,sDAAsD;AACtD,4BAA4B;AAC5B,8BAA8B;AAC9B,sDAAsD;AACtD,kBAAkB;AAClB,cAAc;AACd,iCAAiC;AAEjC,2CAA2C;AAC3C,kGAAkG;AAClG,kHAAkH;AAClH,YAAY;AAEZ,oCAAoC;AAEpC,2EAA2E;AAC3E,YAAY;AACZ,SAAS;AACT,0CAA0C;AAC1C,uBAAuB;AACvB,0DAA0D;AAC1D,UAAU;AACV,sDAAsD;AACtD,iBAAiB;AACjB,MAAM;AAEN,SAAS;AACT,eAAe;IACb,KAAK,EAAE,KAAK,EAAE,OAAgB,EAAE,GAAQ,EAAE,IAAsB,EAAqB,EAAE;QACrF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAChC,MAAM,YAAY,GAAG,GAAG,CAAC,YAAY,CAAA;QACrC,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAEvC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,IAAI,QAAQ,CAAC,qBAAqB,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;QAC7D,CAAC;QAED,+DAA+D;QAC/D,qCAAqC;QACrC,MAAM,EAAE,GAAG,GAAG,CAAC,gBAAgB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;QAClD,MAAM,aAAa,GAAG,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAElD,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACxC,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;YACpD,IAAI,CAAC,aAAa,IAAI,aAAa,KAAK,WAAW,EAAE,CAAC;gBACpD,OAAO,IAAI,QAAQ,CAAC,4CAA4C,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;YACpF,CAAC;YAED,OAAO,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACrC,CAAC;QAED,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;YACxB,MAAM,EAAE,GAAG;YACX,UAAU,EAAE,aAAa;YACzB,OAAO,EAAE;gBACP,cAAc,EAAE,YAAY;aAC7B;SACF,CAAC,CAAA;IACJ,CAAC;CACF,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAA"}
|
package/dist/common/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sync-impl/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA"}
|
package/dist/sync-impl/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sync-impl/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA"}
|
package/src/cf-worker/index.ts
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/// <reference no-default-lib="true"/>
|
|
2
|
-
/// <reference lib="esnext" />
|
|
3
|
-
|
|
4
|
-
// import { EncodedAny } from '@livestore/common/schema'
|
|
5
|
-
// import { Effect, HttpServer, Schema } from '@livestore/utils/effect'
|
|
6
|
-
|
|
7
|
-
import type { Env } from './durable-object.js'
|
|
8
|
-
|
|
9
|
-
export * from './durable-object.js'
|
|
10
|
-
|
|
11
|
-
// const handleRequest = (request: Request, env: Env) =>
|
|
12
|
-
// HttpServer.router.empty.pipe(
|
|
13
|
-
// HttpServer.router.get(
|
|
14
|
-
// '/websocket',
|
|
15
|
-
// Effect.gen(function* () {
|
|
16
|
-
// // This example will refer to the same Durable Object instance,
|
|
17
|
-
// // since the name "foo" is hardcoded.
|
|
18
|
-
// const id = env.WEBSOCKET_SERVER.idFromName('foo')
|
|
19
|
-
// const durableObject = env.WEBSOCKET_SERVER.get(id)
|
|
20
|
-
|
|
21
|
-
// HttpServer.
|
|
22
|
-
|
|
23
|
-
// // Expect to receive a WebSocket Upgrade request.
|
|
24
|
-
// // If there is one, accept the request and return a WebSocket Response.
|
|
25
|
-
// const headerRes = yield* HttpServer.request
|
|
26
|
-
// .schemaHeaders(
|
|
27
|
-
// Schema.Struct({
|
|
28
|
-
// Upgrade: Schema.Literal('websocket'),
|
|
29
|
-
// }),
|
|
30
|
-
// )
|
|
31
|
-
// .pipe(Effect.either)
|
|
32
|
-
|
|
33
|
-
// if (headerRes._tag === 'Left') {
|
|
34
|
-
// // return new Response('Durable Object expected Upgrade: websocket', { status: 426 })
|
|
35
|
-
// return yield* HttpServer.response.text('Durable Object expected Upgrade: websocket', { status: 426 })
|
|
36
|
-
// }
|
|
37
|
-
|
|
38
|
-
// HttpServer.response.empty
|
|
39
|
-
|
|
40
|
-
// return yield* Effect.promise(() => durableObject.fetch(request))
|
|
41
|
-
// }),
|
|
42
|
-
// ),
|
|
43
|
-
// HttpServer.router.catchAll((e) => {
|
|
44
|
-
// console.log(e)
|
|
45
|
-
// return HttpServer.response.empty({ status: 400 })
|
|
46
|
-
// }),
|
|
47
|
-
// (_) => HttpServer.app.toWebHandler(_)(request),
|
|
48
|
-
// // request
|
|
49
|
-
// )
|
|
50
|
-
|
|
51
|
-
// Worker
|
|
52
|
-
export default {
|
|
53
|
-
fetch: async (request: Request, env: Env, _ctx: ExecutionContext): Promise<Response> => {
|
|
54
|
-
const url = new URL(request.url)
|
|
55
|
-
const searchParams = url.searchParams
|
|
56
|
-
const roomId = searchParams.get('room')
|
|
57
|
-
|
|
58
|
-
if (roomId === null) {
|
|
59
|
-
return new Response('Room ID is required', { status: 400 })
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// This example will refer to the same Durable Object instance,
|
|
63
|
-
// since the name "foo" is hardcoded.
|
|
64
|
-
const id = env.WEBSOCKET_SERVER.idFromName(roomId)
|
|
65
|
-
const durableObject = env.WEBSOCKET_SERVER.get(id)
|
|
66
|
-
|
|
67
|
-
if (url.pathname.endsWith('/websocket')) {
|
|
68
|
-
const upgradeHeader = request.headers.get('Upgrade')
|
|
69
|
-
if (!upgradeHeader || upgradeHeader !== 'websocket') {
|
|
70
|
-
return new Response('Durable Object expected Upgrade: websocket', { status: 426 })
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return durableObject.fetch(request)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return new Response(null, {
|
|
77
|
-
status: 400,
|
|
78
|
-
statusText: 'Bad Request',
|
|
79
|
-
headers: {
|
|
80
|
-
'Content-Type': 'text/plain',
|
|
81
|
-
},
|
|
82
|
-
})
|
|
83
|
-
},
|
|
84
|
-
}
|
|
File without changes
|
|
File without changes
|