@livestore/sync-cf 0.3.0-dev.5 → 0.3.0-dev.7
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 +18 -22
- package/dist/cf-worker/durable-object.d.ts.map +1 -1
- package/dist/cf-worker/durable-object.js +114 -107
- package/dist/cf-worker/durable-object.js.map +1 -1
- package/dist/cf-worker/index.d.ts +1 -6
- package/dist/cf-worker/index.d.ts.map +1 -1
- package/dist/cf-worker/index.js +30 -64
- package/dist/cf-worker/index.js.map +1 -1
- package/dist/cf-worker/make-worker.d.ts +6 -0
- package/dist/cf-worker/make-worker.d.ts.map +1 -0
- package/dist/cf-worker/make-worker.js +31 -0
- package/dist/cf-worker/make-worker.js.map +1 -0
- 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/types.d.ts +2 -0
- package/dist/cf-worker/types.d.ts.map +1 -0
- package/dist/cf-worker/types.js +2 -0
- package/dist/cf-worker/types.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 +31 -0
- package/dist/cf-worker/worker.js.map +1 -0
- package/dist/common/mod.d.ts +2 -0
- package/dist/common/mod.d.ts.map +1 -0
- package/dist/common/mod.js +2 -0
- package/dist/common/mod.js.map +1 -0
- 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.js +3 -3
- package/dist/sync-impl/ws-impl.js.map +1 -1
- package/package.json +15 -13
- package/src/cf-worker/durable-object.ts +154 -132
- package/src/cf-worker/mod.ts +2 -0
- package/src/cf-worker/worker.ts +41 -0
- package/src/sync-impl/ws-impl.ts +3 -3
- 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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/cf-worker/worker.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,UAAU,GAAG,GAAa,EAAE;IACvC,OAAO;QACL,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YAClC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAChC,MAAM,YAAY,GAAG,GAAG,CAAC,YAAY,CAAA;YACrC,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;YAEvC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBACpB,OAAO,IAAI,QAAQ,CAAC,qBAAqB,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;YAC7D,CAAC;YAED,+DAA+D;YAC/D,qCAAqC;YACrC,MAAM,EAAE,GAAG,GAAG,CAAC,gBAAgB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;YAClD,MAAM,aAAa,GAAG,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YAElD,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;gBACxC,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;gBACpD,IAAI,CAAC,aAAa,IAAI,aAAa,KAAK,WAAW,EAAE,CAAC;oBACpD,OAAO,IAAI,QAAQ,CAAC,4CAA4C,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;gBACpF,CAAC;gBAED,OAAO,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YACrC,CAAC;YAED,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;gBACxB,MAAM,EAAE,GAAG;gBACX,UAAU,EAAE,aAAa;gBACzB,OAAO,EAAE;oBACP,cAAc,EAAE,YAAY;iBAC7B;aACF,CAAC,CAAA;QACJ,CAAC;KACF,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/common/mod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/common/mod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/sync-impl/mod.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/sync-impl/mod.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA"}
|
|
@@ -3,7 +3,7 @@ import { InvalidPullError, InvalidPushError } from '@livestore/common';
|
|
|
3
3
|
import { pick } from '@livestore/utils';
|
|
4
4
|
import { Deferred, Effect, Option, PubSub, Queue, Schedule, Schema, Stream, SubscriptionRef, WebSocket, } from '@livestore/utils/effect';
|
|
5
5
|
import { nanoid } from '@livestore/utils/nanoid';
|
|
6
|
-
import { WSMessage } from '../common/
|
|
6
|
+
import { WSMessage } from '../common/mod.js';
|
|
7
7
|
export const makeWsSync = (options) => Effect.gen(function* () {
|
|
8
8
|
const wsUrl = `${options.url}/websocket?room=${options.roomId}`;
|
|
9
9
|
const { isConnected, incomingMessages, send } = yield* connect(wsUrl);
|
|
@@ -52,8 +52,8 @@ const connect = (wsUrl) => Effect.gen(function* () {
|
|
|
52
52
|
yield* waitUntilOnline;
|
|
53
53
|
yield* Effect.spanEvent(`Sending message: ${message._tag}`, message._tag === 'WSMessage.PushReq'
|
|
54
54
|
? {
|
|
55
|
-
id: message.batch[0].id
|
|
56
|
-
parentId: message.batch[0].parentId
|
|
55
|
+
id: message.batch[0].id,
|
|
56
|
+
parentId: message.batch[0].parentId,
|
|
57
57
|
batchLength: message.batch.length,
|
|
58
58
|
}
|
|
59
59
|
: message._tag === 'WSMessage.PullReq'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ws-impl.js","sourceRoot":"","sources":["../../src/sync-impl/ws-impl.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAG3B,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACtE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAEvC,OAAO,EACL,QAAQ,EACR,MAAM,EACN,MAAM,EACN,MAAM,EACN,KAAK,EACL,QAAQ,EACR,MAAM,EACN,MAAM,EACN,eAAe,EACf,SAAS,GACV,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEhD,OAAO,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"ws-impl.js","sourceRoot":"","sources":["../../src/sync-impl/ws-impl.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,33 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livestore/sync-cf",
|
|
3
|
-
"version": "0.3.0-dev.
|
|
3
|
+
"version": "0.3.0-dev.7",
|
|
4
4
|
"type": "module",
|
|
5
|
+
"sideEffects": false,
|
|
5
6
|
"exports": {
|
|
6
7
|
".": {
|
|
7
|
-
"types": "./dist/sync-impl/
|
|
8
|
-
"default": "./dist/sync-impl/
|
|
8
|
+
"types": "./dist/sync-impl/mod.d.ts",
|
|
9
|
+
"default": "./dist/sync-impl/mod.js"
|
|
10
|
+
},
|
|
11
|
+
"./cf-worker": {
|
|
12
|
+
"types": "./dist/cf-worker/mod.d.ts",
|
|
13
|
+
"default": "./dist/cf-worker/mod.js"
|
|
9
14
|
}
|
|
10
15
|
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@livestore/common": "0.3.0-dev.7",
|
|
18
|
+
"@livestore/utils": "0.3.0-dev.7"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@cloudflare/workers-types": "^4.20241022.0"
|
|
22
|
+
},
|
|
11
23
|
"files": [
|
|
12
24
|
"dist",
|
|
13
25
|
"src",
|
|
14
26
|
"package.json",
|
|
15
27
|
"README.md"
|
|
16
28
|
],
|
|
17
|
-
"dependencies": {
|
|
18
|
-
"@livestore/common": "0.3.0-dev.5",
|
|
19
|
-
"@livestore/utils": "0.3.0-dev.5"
|
|
20
|
-
},
|
|
21
|
-
"devDependencies": {
|
|
22
|
-
"@cloudflare/workers-types": "4.20241022.0",
|
|
23
|
-
"wrangler": "^3.84.0"
|
|
24
|
-
},
|
|
25
29
|
"publishConfig": {
|
|
26
30
|
"access": "public"
|
|
27
31
|
},
|
|
28
32
|
"scripts": {
|
|
29
|
-
"dev": "wrangler dev --inspector-port 9230",
|
|
30
|
-
"deploy": "wrangler publish",
|
|
31
33
|
"test": "echo 'No tests yet'"
|
|
32
34
|
}
|
|
33
35
|
}
|
|
@@ -4,11 +4,11 @@ import { shouldNeverHappen } from '@livestore/utils'
|
|
|
4
4
|
import { Effect, Logger, LogLevel, Option, Schema } from '@livestore/utils/effect'
|
|
5
5
|
import { DurableObject } from 'cloudflare:workers'
|
|
6
6
|
|
|
7
|
-
import { WSMessage } from '../common/
|
|
7
|
+
import { WSMessage } from '../common/mod.js'
|
|
8
8
|
import type { SyncMetadata } from '../common/ws-message-types.js'
|
|
9
9
|
|
|
10
10
|
export interface Env {
|
|
11
|
-
WEBSOCKET_SERVER: DurableObjectNamespace
|
|
11
|
+
WEBSOCKET_SERVER: DurableObjectNamespace
|
|
12
12
|
DB: D1Database
|
|
13
13
|
ADMIN_SECRET: string
|
|
14
14
|
}
|
|
@@ -34,177 +34,199 @@ export const mutationLogTable = DbSchema.table('__unused', {
|
|
|
34
34
|
*
|
|
35
35
|
* Changing this version number will lead to a "soft reset".
|
|
36
36
|
*/
|
|
37
|
-
const PERSISTENCE_FORMAT_VERSION = 2
|
|
37
|
+
export const PERSISTENCE_FORMAT_VERSION = 2
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
export type MakeDurableObjectClassOptions = {
|
|
40
|
+
onPush?: (message: WSMessage.PushReq) => Effect.Effect<void> | Promise<void>
|
|
41
|
+
onPull?: (message: WSMessage.PullReq) => Effect.Effect<void> | Promise<void>
|
|
42
|
+
}
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
export type MakeDurableObjectClass = (options?: MakeDurableObjectClassOptions) => {
|
|
45
|
+
new (ctx: DurableObjectState, env: Env): DurableObject<Env>
|
|
46
|
+
}
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
export const makeDurableObject: MakeDurableObjectClass = (options) => {
|
|
49
|
+
return class WebSocketServerBase extends DurableObject<Env> {
|
|
50
|
+
dbName = `mutation_log_${PERSISTENCE_FORMAT_VERSION}_${this.ctx.id.toString()}`
|
|
51
|
+
storage = makeStorage(this.ctx, this.env, this.dbName)
|
|
51
52
|
|
|
52
|
-
|
|
53
|
+
constructor(ctx: DurableObjectState, env: Env) {
|
|
54
|
+
super(ctx, env)
|
|
55
|
+
}
|
|
53
56
|
|
|
54
|
-
|
|
57
|
+
fetch = async (_request: Request) =>
|
|
58
|
+
Effect.gen(this, function* () {
|
|
59
|
+
const { 0: client, 1: server } = new WebSocketPair()
|
|
55
60
|
|
|
56
|
-
|
|
57
|
-
new WebSocketRequestResponsePair(
|
|
58
|
-
encodeIncomingMessage(WSMessage.Ping.make({ requestId: 'ping' })),
|
|
59
|
-
encodeOutgoingMessage(WSMessage.Pong.make({ requestId: 'ping' })),
|
|
60
|
-
),
|
|
61
|
-
)
|
|
61
|
+
// See https://developers.cloudflare.com/durable-objects/examples/websocket-hibernation-server
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
this.env.DB.exec(`CREATE TABLE IF NOT EXISTS ${this.dbName} (${colSpec}) strict`)
|
|
63
|
+
this.ctx.acceptWebSocket(server)
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
65
|
+
this.ctx.setWebSocketAutoResponse(
|
|
66
|
+
new WebSocketRequestResponsePair(
|
|
67
|
+
encodeIncomingMessage(WSMessage.Ping.make({ requestId: 'ping' })),
|
|
68
|
+
encodeOutgoingMessage(WSMessage.Pong.make({ requestId: 'ping' })),
|
|
69
|
+
),
|
|
70
|
+
)
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const decodedMessageRes = decodeIncomingMessage(message)
|
|
72
|
+
const colSpec = makeColumnSpec(mutationLogTable.sqliteDef.ast)
|
|
73
|
+
this.env.DB.exec(`CREATE TABLE IF NOT EXISTS ${this.dbName} (${colSpec}) strict`)
|
|
75
74
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
return new Response(null, {
|
|
76
|
+
status: 101,
|
|
77
|
+
webSocket: client,
|
|
78
|
+
})
|
|
79
|
+
}).pipe(Effect.tapCauseLogPretty, Effect.runPromise)
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
webSocketMessage = (ws: WebSocketClient, message: ArrayBuffer | string) =>
|
|
82
|
+
Effect.gen(this, function* () {
|
|
83
|
+
const decodedMessageRes = decodeIncomingMessage(message)
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const CHUNK_SIZE = 100
|
|
85
|
+
if (decodedMessageRes._tag === 'Left') {
|
|
86
|
+
console.error('Invalid message received', decodedMessageRes.left)
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
const decodedMessage = decodedMessageRes.right
|
|
91
|
+
const requestId = decodedMessage.requestId
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
try {
|
|
94
|
+
switch (decodedMessage._tag) {
|
|
95
|
+
case 'WSMessage.PullReq': {
|
|
96
|
+
if (options?.onPull) {
|
|
97
|
+
yield* Effect.tryAll(() => options.onPull!(decodedMessage))
|
|
98
|
+
}
|
|
96
99
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
+
const cursor = decodedMessage.cursor
|
|
101
|
+
const CHUNK_SIZE = 100
|
|
102
|
+
|
|
103
|
+
// TODO use streaming
|
|
104
|
+
const remainingEvents = [...(yield* Effect.promise(() => this.storage.getEvents(cursor)))]
|
|
100
105
|
|
|
101
|
-
if
|
|
102
|
-
|
|
106
|
+
// NOTE we want to make sure the WS server responds at least once with `InitRes` even if `events` is empty
|
|
107
|
+
while (true) {
|
|
108
|
+
const events = remainingEvents.splice(0, CHUNK_SIZE)
|
|
109
|
+
|
|
110
|
+
ws.send(
|
|
111
|
+
encodeOutgoingMessage(
|
|
112
|
+
WSMessage.PullRes.make({ events, remaining: remainingEvents.length, requestId }),
|
|
113
|
+
),
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
if (remainingEvents.length === 0) {
|
|
117
|
+
break
|
|
118
|
+
}
|
|
103
119
|
}
|
|
104
|
-
}
|
|
105
120
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const expectedParentId = latestEvent?.id ?? EventId.ROOT.global
|
|
112
|
-
|
|
113
|
-
let i = 0
|
|
114
|
-
for (const mutationEventEncoded of decodedMessage.batch) {
|
|
115
|
-
if (mutationEventEncoded.parentId !== expectedParentId + i) {
|
|
116
|
-
const err = WSMessage.Error.make({
|
|
117
|
-
message: `Invalid parent id. Received ${mutationEventEncoded.parentId} but expected ${expectedParentId}`,
|
|
118
|
-
requestId,
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
yield* Effect.fail(err).pipe(Effect.ignoreLogged)
|
|
122
|
-
|
|
123
|
-
ws.send(encodeOutgoingMessage(err))
|
|
124
|
-
return
|
|
121
|
+
break
|
|
122
|
+
}
|
|
123
|
+
case 'WSMessage.PushReq': {
|
|
124
|
+
if (options?.onPush) {
|
|
125
|
+
yield* Effect.tryAll(() => options.onPush!(decodedMessage))
|
|
125
126
|
}
|
|
126
127
|
|
|
127
|
-
// TODO
|
|
128
|
+
// TODO check whether we could use the Durable Object storage for this to speed up the lookup
|
|
129
|
+
const latestEvent = yield* Effect.promise(() => this.storage.getLatestEvent())
|
|
130
|
+
const expectedParentId = latestEvent?.id ?? EventId.ROOT.global
|
|
128
131
|
|
|
129
|
-
|
|
132
|
+
let i = 0
|
|
133
|
+
for (const mutationEventEncoded of decodedMessage.batch) {
|
|
134
|
+
if (mutationEventEncoded.parentId !== expectedParentId + i) {
|
|
135
|
+
const err = WSMessage.Error.make({
|
|
136
|
+
message: `Invalid parent id. Received ${mutationEventEncoded.parentId} but expected ${expectedParentId}`,
|
|
137
|
+
requestId,
|
|
138
|
+
})
|
|
130
139
|
|
|
131
|
-
|
|
132
|
-
const storePromise = this.storage.appendEvent(mutationEventEncoded, createdAt)
|
|
140
|
+
yield* Effect.fail(err).pipe(Effect.ignoreLogged)
|
|
133
141
|
|
|
134
|
-
|
|
142
|
+
ws.send(encodeOutgoingMessage(err))
|
|
143
|
+
return
|
|
144
|
+
}
|
|
135
145
|
|
|
136
|
-
|
|
146
|
+
// TODO handle clientId unique conflict
|
|
137
147
|
|
|
138
|
-
|
|
148
|
+
const createdAt = new Date().toISOString()
|
|
139
149
|
|
|
140
|
-
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
metadata: Option.some({ createdAt }),
|
|
146
|
-
}),
|
|
150
|
+
// NOTE we're currently not blocking on this to allow broadcasting right away
|
|
151
|
+
const storePromise = this.storage.appendEvent(mutationEventEncoded, createdAt)
|
|
152
|
+
|
|
153
|
+
ws.send(
|
|
154
|
+
encodeOutgoingMessage(WSMessage.PushAck.make({ mutationId: mutationEventEncoded.id, requestId })),
|
|
147
155
|
)
|
|
148
156
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
157
|
+
// console.debug(`Broadcasting mutation event to ${this.subscribedWebSockets.size} clients`)
|
|
158
|
+
|
|
159
|
+
const connectedClients = this.ctx.getWebSockets()
|
|
160
|
+
|
|
161
|
+
if (connectedClients.length > 0) {
|
|
162
|
+
const broadcastMessage = encodeOutgoingMessage(
|
|
163
|
+
// TODO refactor to batch api
|
|
164
|
+
WSMessage.PushBroadcast.make({
|
|
165
|
+
mutationEventEncoded,
|
|
166
|
+
metadata: Option.some({ createdAt }),
|
|
167
|
+
}),
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
for (const conn of connectedClients) {
|
|
171
|
+
console.log('Broadcasting to client', conn === ws ? 'self' : 'other')
|
|
172
|
+
// if (conn !== ws) {
|
|
173
|
+
conn.send(broadcastMessage)
|
|
174
|
+
// }
|
|
175
|
+
}
|
|
154
176
|
}
|
|
155
|
-
}
|
|
156
177
|
|
|
157
|
-
|
|
178
|
+
yield* Effect.promise(() => storePromise)
|
|
158
179
|
|
|
159
|
-
|
|
160
|
-
|
|
180
|
+
i++
|
|
181
|
+
}
|
|
161
182
|
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
case 'WSMessage.AdminResetRoomReq': {
|
|
165
|
-
if (decodedMessage.adminSecret !== this.env.ADMIN_SECRET) {
|
|
166
|
-
ws.send(encodeOutgoingMessage(WSMessage.Error.make({ message: 'Invalid admin secret', requestId })))
|
|
167
|
-
return
|
|
183
|
+
break
|
|
168
184
|
}
|
|
185
|
+
case 'WSMessage.AdminResetRoomReq': {
|
|
186
|
+
if (decodedMessage.adminSecret !== this.env.ADMIN_SECRET) {
|
|
187
|
+
ws.send(encodeOutgoingMessage(WSMessage.Error.make({ message: 'Invalid admin secret', requestId })))
|
|
188
|
+
return
|
|
189
|
+
}
|
|
169
190
|
|
|
170
|
-
|
|
171
|
-
|
|
191
|
+
yield* Effect.promise(() => this.storage.resetRoom())
|
|
192
|
+
ws.send(encodeOutgoingMessage(WSMessage.AdminResetRoomRes.make({ requestId })))
|
|
172
193
|
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
case 'WSMessage.AdminInfoReq': {
|
|
176
|
-
if (decodedMessage.adminSecret !== this.env.ADMIN_SECRET) {
|
|
177
|
-
ws.send(encodeOutgoingMessage(WSMessage.Error.make({ message: 'Invalid admin secret', requestId })))
|
|
178
|
-
return
|
|
194
|
+
break
|
|
179
195
|
}
|
|
196
|
+
case 'WSMessage.AdminInfoReq': {
|
|
197
|
+
if (decodedMessage.adminSecret !== this.env.ADMIN_SECRET) {
|
|
198
|
+
ws.send(encodeOutgoingMessage(WSMessage.Error.make({ message: 'Invalid admin secret', requestId })))
|
|
199
|
+
return
|
|
200
|
+
}
|
|
180
201
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
202
|
+
ws.send(
|
|
203
|
+
encodeOutgoingMessage(
|
|
204
|
+
WSMessage.AdminInfoRes.make({ requestId, info: { durableObjectId: this.ctx.id.toString() } }),
|
|
205
|
+
),
|
|
206
|
+
)
|
|
186
207
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
208
|
+
break
|
|
209
|
+
}
|
|
210
|
+
default: {
|
|
211
|
+
console.error('unsupported message', decodedMessage)
|
|
212
|
+
return shouldNeverHappen()
|
|
213
|
+
}
|
|
192
214
|
}
|
|
215
|
+
} catch (error: any) {
|
|
216
|
+
ws.send(encodeOutgoingMessage(WSMessage.Error.make({ message: error.message, requestId })))
|
|
193
217
|
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
Effect.provide(Logger.pretty),
|
|
202
|
-
Effect.runPromise,
|
|
203
|
-
)
|
|
218
|
+
}).pipe(
|
|
219
|
+
Effect.withSpan('@livestore/sync-cf:durable-object:webSocketMessage'),
|
|
220
|
+
Effect.tapCauseLogPretty,
|
|
221
|
+
Logger.withMinimumLogLevel(LogLevel.Debug),
|
|
222
|
+
Effect.provide(Logger.pretty),
|
|
223
|
+
Effect.runPromise,
|
|
224
|
+
)
|
|
204
225
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
226
|
+
webSocketClose = async (ws: WebSocketClient, code: number, _reason: string, _wasClean: boolean) => {
|
|
227
|
+
// If the client closes the connection, the runtime will invoke the webSocketClose() handler.
|
|
228
|
+
ws.close(code, 'Durable Object is closing WebSocket')
|
|
229
|
+
}
|
|
208
230
|
}
|
|
209
231
|
}
|
|
210
232
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Env } from './durable-object.js'
|
|
2
|
+
|
|
3
|
+
export type CFWorker = {
|
|
4
|
+
fetch: (request: Request, env: Env, ctx: ExecutionContext) => Promise<Response>
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const makeWorker = (): CFWorker => {
|
|
8
|
+
return {
|
|
9
|
+
fetch: async (request, env, _ctx) => {
|
|
10
|
+
const url = new URL(request.url)
|
|
11
|
+
const searchParams = url.searchParams
|
|
12
|
+
const roomId = searchParams.get('room')
|
|
13
|
+
|
|
14
|
+
if (roomId === null) {
|
|
15
|
+
return new Response('Room ID is required', { status: 400 })
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// This example will refer to the same Durable Object instance,
|
|
19
|
+
// since the name "foo" is hardcoded.
|
|
20
|
+
const id = env.WEBSOCKET_SERVER.idFromName(roomId)
|
|
21
|
+
const durableObject = env.WEBSOCKET_SERVER.get(id)
|
|
22
|
+
|
|
23
|
+
if (url.pathname.endsWith('/websocket')) {
|
|
24
|
+
const upgradeHeader = request.headers.get('Upgrade')
|
|
25
|
+
if (!upgradeHeader || upgradeHeader !== 'websocket') {
|
|
26
|
+
return new Response('Durable Object expected Upgrade: websocket', { status: 426 })
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return durableObject.fetch(request)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return new Response(null, {
|
|
33
|
+
status: 400,
|
|
34
|
+
statusText: 'Bad Request',
|
|
35
|
+
headers: {
|
|
36
|
+
'Content-Type': 'text/plain',
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
}
|
package/src/sync-impl/ws-impl.ts
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
} from '@livestore/utils/effect'
|
|
19
19
|
import { nanoid } from '@livestore/utils/nanoid'
|
|
20
20
|
|
|
21
|
-
import { WSMessage } from '../common/
|
|
21
|
+
import { WSMessage } from '../common/mod.js'
|
|
22
22
|
import type { SyncMetadata } from '../common/ws-message-types.js'
|
|
23
23
|
|
|
24
24
|
export interface WsSyncOptions extends SyncBackendOptionsBase {
|
|
@@ -127,8 +127,8 @@ const connect = (wsUrl: string) =>
|
|
|
127
127
|
`Sending message: ${message._tag}`,
|
|
128
128
|
message._tag === 'WSMessage.PushReq'
|
|
129
129
|
? {
|
|
130
|
-
id: message.batch[0]!.id
|
|
131
|
-
parentId: message.batch[0]!.parentId
|
|
130
|
+
id: message.batch[0]!.id,
|
|
131
|
+
parentId: message.batch[0]!.parentId,
|
|
132
132
|
batchLength: message.batch.length,
|
|
133
133
|
}
|
|
134
134
|
: message._tag === 'WSMessage.PullReq'
|
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
|