@livestore/sync-cf 0.0.0-snapshot-4c2ee347c9a2ee93b7d67a7652d1db36f5b7ee30 → 0.0.0-snapshot-aed277ba0960f72b8d464508961ab4aec1881230
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 +40 -34
- package/dist/cf-worker/durable-object.d.ts.map +1 -1
- package/dist/cf-worker/durable-object.js +159 -124
- 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 +92 -216
- package/dist/common/ws-message-types.d.ts.map +1 -1
- package/dist/common/ws-message-types.js +13 -9
- 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 +5 -13
- package/dist/sync-impl/ws-impl.d.ts.map +1 -1
- package/dist/sync-impl/ws-impl.js +69 -69
- package/dist/sync-impl/ws-impl.js.map +1 -1
- package/package.json +17 -8
- package/src/cf-worker/durable-object.ts +236 -153
- package/src/cf-worker/mod.ts +2 -0
- package/src/cf-worker/worker.ts +39 -0
- package/src/common/ws-message-types.ts +18 -9
- package/src/sync-impl/ws-impl.ts +120 -121
- 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/tsconfig.json +0 -12
- package/wrangler.toml +0 -21
- /package/src/common/{index.ts → mod.ts} +0 -0
- /package/src/sync-impl/{index.ts → mod.ts} +0 -0
|
@@ -1,44 +1,50 @@
|
|
|
1
|
-
import { DbSchema
|
|
2
|
-
import { Schema } from '@livestore/utils/effect';
|
|
1
|
+
import { DbSchema } from '@livestore/common/schema';
|
|
2
|
+
import { Effect, Option, Schema } from '@livestore/utils/effect';
|
|
3
3
|
import { DurableObject } from 'cloudflare:workers';
|
|
4
|
+
import { WSMessage } from '../common/mod.js';
|
|
4
5
|
export interface Env {
|
|
5
|
-
WEBSOCKET_SERVER: DurableObjectNamespace
|
|
6
|
+
WEBSOCKET_SERVER: DurableObjectNamespace;
|
|
6
7
|
DB: D1Database;
|
|
7
8
|
ADMIN_SECRET: string;
|
|
8
9
|
}
|
|
9
|
-
type WebSocketClient = WebSocket;
|
|
10
10
|
export declare const mutationLogTable: DbSchema.TableDef<{
|
|
11
11
|
name: "__unused";
|
|
12
12
|
columns: {
|
|
13
|
-
|
|
13
|
+
id: {
|
|
14
14
|
columnType: "integer";
|
|
15
|
-
schema: Schema.Schema<number
|
|
16
|
-
default:
|
|
15
|
+
schema: Schema.Schema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
|
|
16
|
+
default: Option.None<never>;
|
|
17
17
|
nullable: false;
|
|
18
18
|
primaryKey: true;
|
|
19
19
|
};
|
|
20
|
-
|
|
20
|
+
parentId: {
|
|
21
21
|
columnType: "integer";
|
|
22
|
-
schema: Schema.Schema<number
|
|
23
|
-
default:
|
|
22
|
+
schema: Schema.Schema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
|
|
23
|
+
default: Option.None<never>;
|
|
24
24
|
nullable: false;
|
|
25
25
|
primaryKey: false;
|
|
26
26
|
};
|
|
27
27
|
mutation: {
|
|
28
28
|
columnType: "text";
|
|
29
29
|
schema: Schema.Schema<string, string, never>;
|
|
30
|
-
default:
|
|
30
|
+
default: Option.None<never>;
|
|
31
31
|
nullable: false;
|
|
32
32
|
primaryKey: false;
|
|
33
33
|
};
|
|
34
34
|
args: {
|
|
35
35
|
columnType: "text";
|
|
36
36
|
schema: Schema.Schema<any, string, never>;
|
|
37
|
-
default:
|
|
37
|
+
default: Option.None<never>;
|
|
38
|
+
nullable: false;
|
|
39
|
+
primaryKey: false;
|
|
40
|
+
};
|
|
41
|
+
createdAt: {
|
|
42
|
+
columnType: "text";
|
|
43
|
+
schema: Schema.Schema<string, string, never>;
|
|
44
|
+
default: Option.None<never>;
|
|
38
45
|
nullable: false;
|
|
39
46
|
primaryKey: false;
|
|
40
47
|
};
|
|
41
|
-
id: DbSchema.SqliteDsl.ColumnDefinition<string, string>;
|
|
42
48
|
};
|
|
43
49
|
indexes?: ReadonlyArray<DbSchema.SqliteDsl.Index>;
|
|
44
50
|
ast: import("@livestore/db-schema/dist/ast/sqlite.js").Table;
|
|
@@ -47,32 +53,32 @@ export declare const mutationLogTable: DbSchema.TableDef<{
|
|
|
47
53
|
disableAutomaticIdColumn: false;
|
|
48
54
|
deriveMutations: never;
|
|
49
55
|
isSingleColumn: false;
|
|
50
|
-
requiredInsertColumnNames: "
|
|
56
|
+
requiredInsertColumnNames: "createdAt" | "mutation" | "args" | "id" | "parentId";
|
|
51
57
|
}, Schema.Schema<{
|
|
52
|
-
readonly
|
|
53
|
-
readonly
|
|
58
|
+
readonly id: number & import("effect/Brand").Brand<"GlobalEventId">;
|
|
59
|
+
readonly parentId: number & import("effect/Brand").Brand<"GlobalEventId">;
|
|
54
60
|
readonly mutation: string;
|
|
55
61
|
readonly args: any;
|
|
56
|
-
readonly
|
|
62
|
+
readonly createdAt: string;
|
|
57
63
|
}, {
|
|
58
|
-
readonly
|
|
59
|
-
readonly
|
|
64
|
+
readonly id: number;
|
|
65
|
+
readonly parentId: number;
|
|
60
66
|
readonly mutation: string;
|
|
61
67
|
readonly args: string;
|
|
62
|
-
readonly
|
|
68
|
+
readonly createdAt: string;
|
|
63
69
|
}, never>>;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
export
|
|
70
|
+
/**
|
|
71
|
+
* Needs to be bumped when the storage format changes (e.g. mutationLogTable schema changes)
|
|
72
|
+
*
|
|
73
|
+
* Changing this version number will lead to a "soft reset".
|
|
74
|
+
*/
|
|
75
|
+
export declare const PERSISTENCE_FORMAT_VERSION = 2;
|
|
76
|
+
export type MakeDurableObjectClassOptions = {
|
|
77
|
+
onPush?: (message: WSMessage.PushReq) => Effect.Effect<void> | Promise<void>;
|
|
78
|
+
onPull?: (message: WSMessage.PullReq) => Effect.Effect<void> | Promise<void>;
|
|
79
|
+
};
|
|
80
|
+
export type MakeDurableObjectClass = (options?: MakeDurableObjectClassOptions) => {
|
|
81
|
+
new (ctx: DurableObjectState, env: Env): DurableObject<Env>;
|
|
82
|
+
};
|
|
83
|
+
export declare const makeDurableObject: MakeDurableObjectClass;
|
|
78
84
|
//# sourceMappingURL=durable-object.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"durable-object.d.ts","sourceRoot":"","sources":["../../src/cf-worker/durable-object.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"durable-object.d.ts","sourceRoot":"","sources":["../../src/cf-worker/durable-object.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAA+B,MAAM,0BAA0B,CAAA;AAEhF,OAAO,EAAE,MAAM,EAAoB,MAAM,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAG5C,MAAM,WAAW,GAAG;IAClB,gBAAgB,EAAE,sBAAsB,CAAA;IACxC,EAAE,EAAE,UAAU,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;CACrB;AASD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAO3B,CAAA;AAQF;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,IAAI,CAAA;AAE3C,MAAM,MAAM,6BAA6B,GAAG;IAC1C,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5E,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7E,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,CAAC,EAAE,6BAA6B,KAAK;IAChF,KAAK,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;CAC5D,CAAA;AAED,eAAO,MAAM,iBAAiB,EAAE,sBA6L/B,CAAA"}
|
|
@@ -1,166 +1,201 @@
|
|
|
1
|
-
import { makeColumnSpec
|
|
2
|
-
import { DbSchema,
|
|
1
|
+
import { makeColumnSpec } from '@livestore/common';
|
|
2
|
+
import { DbSchema, EventId } from '@livestore/common/schema';
|
|
3
3
|
import { shouldNeverHappen } from '@livestore/utils';
|
|
4
|
-
import { Effect, Schema } from '@livestore/utils/effect';
|
|
4
|
+
import { Effect, Logger, LogLevel, Option, Schema } from '@livestore/utils/effect';
|
|
5
5
|
import { DurableObject } from 'cloudflare:workers';
|
|
6
|
-
import { WSMessage } from '../common/
|
|
6
|
+
import { WSMessage } from '../common/mod.js';
|
|
7
7
|
const encodeOutgoingMessage = Schema.encodeSync(Schema.parseJson(WSMessage.BackendToClientMessage));
|
|
8
8
|
const encodeIncomingMessage = Schema.encodeSync(Schema.parseJson(WSMessage.ClientToBackendMessage));
|
|
9
9
|
const decodeIncomingMessage = Schema.decodeUnknownEither(Schema.parseJson(WSMessage.ClientToBackendMessage));
|
|
10
|
+
// NOTE actual table name is determined at runtime by `WebSocketServer.dbName`
|
|
10
11
|
export const mutationLogTable = DbSchema.table('__unused', {
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
id: DbSchema.integer({ primaryKey: true, schema: EventId.GlobalEventId }),
|
|
13
|
+
parentId: DbSchema.integer({ schema: EventId.GlobalEventId }),
|
|
13
14
|
mutation: DbSchema.text({}),
|
|
14
15
|
args: DbSchema.text({ schema: Schema.parseJson(Schema.Any) }),
|
|
16
|
+
/** ISO date format. Currently only used for debugging purposes. */
|
|
17
|
+
createdAt: DbSchema.text({}),
|
|
15
18
|
});
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
this.env.DB.exec(`CREATE TABLE IF NOT EXISTS ${this.dbName} (${colSpec}) strict`);
|
|
30
|
-
return new Response(null, {
|
|
31
|
-
status: 101,
|
|
32
|
-
webSocket: client,
|
|
33
|
-
});
|
|
34
|
-
}).pipe(Effect.tapCauseLogPretty, Effect.runPromise);
|
|
35
|
-
webSocketMessage = async (ws, message) => {
|
|
36
|
-
const decodedMessageRes = decodeIncomingMessage(message);
|
|
37
|
-
if (decodedMessageRes._tag === 'Left') {
|
|
38
|
-
console.error('Invalid message received', decodedMessageRes.left);
|
|
39
|
-
return;
|
|
19
|
+
const WebSocketAttachmentSchema = Schema.parseJson(Schema.Struct({
|
|
20
|
+
storeId: Schema.String,
|
|
21
|
+
}));
|
|
22
|
+
/**
|
|
23
|
+
* Needs to be bumped when the storage format changes (e.g. mutationLogTable schema changes)
|
|
24
|
+
*
|
|
25
|
+
* Changing this version number will lead to a "soft reset".
|
|
26
|
+
*/
|
|
27
|
+
export const PERSISTENCE_FORMAT_VERSION = 2;
|
|
28
|
+
export const makeDurableObject = (options) => {
|
|
29
|
+
return class WebSocketServerBase extends DurableObject {
|
|
30
|
+
constructor(ctx, env) {
|
|
31
|
+
super(ctx, env);
|
|
40
32
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
33
|
+
fetch = async (request) => Effect.gen(this, function* () {
|
|
34
|
+
const storeId = getStoreId(request);
|
|
35
|
+
const storage = makeStorage(this.ctx, this.env, storeId);
|
|
36
|
+
const { 0: client, 1: server } = new WebSocketPair();
|
|
37
|
+
// Since we're using websocket hibernation, we need to remember the storeId for subsequent `webSocketMessage` calls
|
|
38
|
+
server.serializeAttachment(Schema.encodeSync(WebSocketAttachmentSchema)({ storeId }));
|
|
39
|
+
// See https://developers.cloudflare.com/durable-objects/examples/websocket-hibernation-server
|
|
40
|
+
this.ctx.acceptWebSocket(server);
|
|
41
|
+
this.ctx.setWebSocketAutoResponse(new WebSocketRequestResponsePair(encodeIncomingMessage(WSMessage.Ping.make({ requestId: 'ping' })), encodeOutgoingMessage(WSMessage.Pong.make({ requestId: 'ping' }))));
|
|
42
|
+
const colSpec = makeColumnSpec(mutationLogTable.sqliteDef.ast);
|
|
43
|
+
this.env.DB.exec(`CREATE TABLE IF NOT EXISTS ${storage.dbName} (${colSpec}) strict`);
|
|
44
|
+
return new Response(null, {
|
|
45
|
+
status: 101,
|
|
46
|
+
webSocket: client,
|
|
47
|
+
});
|
|
48
|
+
}).pipe(Effect.tapCauseLogPretty, Effect.runPromise);
|
|
49
|
+
webSocketMessage = (ws, message) => Effect.gen(this, function* () {
|
|
50
|
+
const decodedMessageRes = decodeIncomingMessage(message);
|
|
51
|
+
if (decodedMessageRes._tag === 'Left') {
|
|
52
|
+
console.error('Invalid message received', decodedMessageRes.left);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const { storeId } = yield* Schema.decode(WebSocketAttachmentSchema)(ws.deserializeAttachment());
|
|
56
|
+
const storage = makeStorage(this.ctx, this.env, storeId);
|
|
57
|
+
const decodedMessage = decodedMessageRes.right;
|
|
58
|
+
const requestId = decodedMessage.requestId;
|
|
59
|
+
try {
|
|
60
|
+
switch (decodedMessage._tag) {
|
|
61
|
+
case 'WSMessage.PullReq': {
|
|
62
|
+
if (options?.onPull) {
|
|
63
|
+
yield* Effect.tryAll(() => options.onPull(decodedMessage));
|
|
64
|
+
}
|
|
65
|
+
const cursor = decodedMessage.cursor;
|
|
66
|
+
const CHUNK_SIZE = 100;
|
|
67
|
+
// TODO use streaming
|
|
68
|
+
const remainingEvents = [...(yield* Effect.promise(() => storage.getEvents(cursor)))];
|
|
69
|
+
// NOTE we want to make sure the WS server responds at least once with `InitRes` even if `events` is empty
|
|
70
|
+
while (true) {
|
|
71
|
+
const events = remainingEvents.splice(0, CHUNK_SIZE);
|
|
72
|
+
ws.send(encodeOutgoingMessage(WSMessage.PullRes.make({ events, remaining: remainingEvents.length, requestId })));
|
|
73
|
+
if (remainingEvents.length === 0) {
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
58
76
|
}
|
|
77
|
+
break;
|
|
59
78
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
79
|
+
case 'WSMessage.PushReq': {
|
|
80
|
+
if (options?.onPush) {
|
|
81
|
+
yield* Effect.tryAll(() => options.onPush(decodedMessage));
|
|
82
|
+
}
|
|
83
|
+
// TODO check whether we could use the Durable Object storage for this to speed up the lookup
|
|
84
|
+
const latestEvent = yield* Effect.promise(() => storage.getLatestEvent());
|
|
85
|
+
const expectedParentId = latestEvent?.id ?? EventId.ROOT.global;
|
|
86
|
+
let i = 0;
|
|
87
|
+
for (const mutationEventEncoded of decodedMessage.batch) {
|
|
88
|
+
if (mutationEventEncoded.parentId !== expectedParentId + i) {
|
|
89
|
+
const err = WSMessage.Error.make({
|
|
90
|
+
message: `Invalid parent id. Received ${mutationEventEncoded.parentId} but expected ${expectedParentId}`,
|
|
91
|
+
requestId,
|
|
92
|
+
});
|
|
93
|
+
yield* Effect.fail(err).pipe(Effect.ignoreLogged);
|
|
94
|
+
ws.send(encodeOutgoingMessage(err));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
// TODO handle clientId unique conflict
|
|
98
|
+
const createdAt = new Date().toISOString();
|
|
99
|
+
// NOTE we're currently not blocking on this to allow broadcasting right away
|
|
100
|
+
const storePromise = storage.appendEvent(mutationEventEncoded, createdAt);
|
|
101
|
+
ws.send(encodeOutgoingMessage(WSMessage.PushAck.make({ mutationId: mutationEventEncoded.id, requestId })));
|
|
102
|
+
// console.debug(`Broadcasting mutation event to ${this.subscribedWebSockets.size} clients`)
|
|
103
|
+
const connectedClients = this.ctx.getWebSockets();
|
|
104
|
+
if (connectedClients.length > 0) {
|
|
105
|
+
const broadcastMessage = encodeOutgoingMessage(
|
|
106
|
+
// TODO refactor to batch api
|
|
107
|
+
WSMessage.PushBroadcast.make({
|
|
108
|
+
mutationEventEncoded,
|
|
109
|
+
metadata: Option.some({ createdAt }),
|
|
110
|
+
}));
|
|
111
|
+
for (const conn of connectedClients) {
|
|
112
|
+
console.log('Broadcasting to client', conn === ws ? 'self' : 'other');
|
|
113
|
+
// if (conn !== ws) {
|
|
114
|
+
conn.send(broadcastMessage);
|
|
115
|
+
// }
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
yield* Effect.promise(() => storePromise);
|
|
119
|
+
i++;
|
|
120
|
+
}
|
|
121
|
+
break;
|
|
72
122
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
: Promise.resolve();
|
|
78
|
-
ws.send(encodeOutgoingMessage(WSMessage.PushAck.make({ mutationId: decodedMessage.mutationEventEncoded.id.global, requestId })));
|
|
79
|
-
// console.debug(`Broadcasting mutation event to ${this.subscribedWebSockets.size} clients`)
|
|
80
|
-
const connectedClients = this.ctx.getWebSockets();
|
|
81
|
-
if (connectedClients.length > 0) {
|
|
82
|
-
const broadcastMessage = encodeOutgoingMessage(WSMessage.PushBroadcast.make({
|
|
83
|
-
mutationEventEncoded: decodedMessage.mutationEventEncoded,
|
|
84
|
-
persisted: decodedMessage.persisted,
|
|
85
|
-
}));
|
|
86
|
-
for (const conn of connectedClients) {
|
|
87
|
-
console.log('Broadcasting to client', conn === ws ? 'self' : 'other');
|
|
88
|
-
// if (conn !== ws) {
|
|
89
|
-
conn.send(broadcastMessage);
|
|
90
|
-
// }
|
|
123
|
+
case 'WSMessage.AdminResetRoomReq': {
|
|
124
|
+
if (decodedMessage.adminSecret !== this.env.ADMIN_SECRET) {
|
|
125
|
+
ws.send(encodeOutgoingMessage(WSMessage.Error.make({ message: 'Invalid admin secret', requestId })));
|
|
126
|
+
return;
|
|
91
127
|
}
|
|
128
|
+
yield* Effect.promise(() => storage.resetRoom());
|
|
129
|
+
ws.send(encodeOutgoingMessage(WSMessage.AdminResetRoomRes.make({ requestId })));
|
|
130
|
+
break;
|
|
92
131
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
ws.send(encodeOutgoingMessage(WSMessage.
|
|
99
|
-
|
|
132
|
+
case 'WSMessage.AdminInfoReq': {
|
|
133
|
+
if (decodedMessage.adminSecret !== this.env.ADMIN_SECRET) {
|
|
134
|
+
ws.send(encodeOutgoingMessage(WSMessage.Error.make({ message: 'Invalid admin secret', requestId })));
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
ws.send(encodeOutgoingMessage(WSMessage.AdminInfoRes.make({ requestId, info: { durableObjectId: this.ctx.id.toString() } })));
|
|
138
|
+
break;
|
|
100
139
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
case 'WSMessage.AdminInfoReq': {
|
|
106
|
-
if (decodedMessage.adminSecret !== this.env.ADMIN_SECRET) {
|
|
107
|
-
ws.send(encodeOutgoingMessage(WSMessage.Error.make({ message: 'Invalid admin secret', requestId })));
|
|
108
|
-
return;
|
|
140
|
+
default: {
|
|
141
|
+
console.error('unsupported message', decodedMessage);
|
|
142
|
+
return shouldNeverHappen();
|
|
109
143
|
}
|
|
110
|
-
ws.send(encodeOutgoingMessage(WSMessage.AdminInfoRes.make({ requestId, info: { durableObjectId: this.ctx.id.toString() } })));
|
|
111
|
-
break;
|
|
112
|
-
}
|
|
113
|
-
default: {
|
|
114
|
-
console.error('unsupported message', decodedMessage);
|
|
115
|
-
return shouldNeverHappen();
|
|
116
144
|
}
|
|
117
145
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
146
|
+
catch (error) {
|
|
147
|
+
ws.send(encodeOutgoingMessage(WSMessage.Error.make({ message: error.message, requestId })));
|
|
148
|
+
}
|
|
149
|
+
}).pipe(Effect.withSpan('@livestore/sync-cf:durable-object:webSocketMessage'), Effect.tapCauseLogPretty, Logger.withMinimumLogLevel(LogLevel.Debug), Effect.provide(Logger.pretty), Effect.runPromise);
|
|
150
|
+
webSocketClose = async (ws, code, _reason, _wasClean) => {
|
|
151
|
+
// If the client closes the connection, the runtime will invoke the webSocketClose() handler.
|
|
152
|
+
ws.close(code, 'Durable Object is closing WebSocket');
|
|
153
|
+
};
|
|
126
154
|
};
|
|
127
|
-
}
|
|
128
|
-
const makeStorage = (ctx, env,
|
|
155
|
+
};
|
|
156
|
+
const makeStorage = (ctx, env, storeId) => {
|
|
157
|
+
const dbName = `mutation_log_${PERSISTENCE_FORMAT_VERSION}_${toValidTableName(storeId)}`;
|
|
129
158
|
const getLatestEvent = async () => {
|
|
130
|
-
const rawEvents = await env.DB.prepare(`SELECT * FROM ${dbName} ORDER BY
|
|
159
|
+
const rawEvents = await env.DB.prepare(`SELECT * FROM ${dbName} ORDER BY id DESC LIMIT 1`).all();
|
|
131
160
|
if (rawEvents.error) {
|
|
132
161
|
throw new Error(rawEvents.error);
|
|
133
162
|
}
|
|
134
|
-
const events = Schema.decodeUnknownSync(Schema.Array(mutationLogTable.schema))(rawEvents.results)
|
|
135
|
-
...e,
|
|
136
|
-
id: { global: e.idGlobal, local: 0 },
|
|
137
|
-
parentId: { global: e.parentIdGlobal, local: 0 },
|
|
138
|
-
}));
|
|
163
|
+
const events = Schema.decodeUnknownSync(Schema.Array(mutationLogTable.schema))(rawEvents.results);
|
|
139
164
|
return events[0];
|
|
140
165
|
};
|
|
141
166
|
const getEvents = async (cursor) => {
|
|
142
|
-
const whereClause = cursor ? `WHERE
|
|
167
|
+
const whereClause = cursor === undefined ? '' : `WHERE id > ${cursor}`;
|
|
168
|
+
const sql = `SELECT * FROM ${dbName} ${whereClause} ORDER BY id ASC`;
|
|
143
169
|
// TODO handle case where `cursor` was not found
|
|
144
|
-
const rawEvents = await env.DB.prepare(
|
|
170
|
+
const rawEvents = await env.DB.prepare(sql).all();
|
|
145
171
|
if (rawEvents.error) {
|
|
146
172
|
throw new Error(rawEvents.error);
|
|
147
173
|
}
|
|
148
|
-
const events = Schema.decodeUnknownSync(Schema.Array(mutationLogTable.schema))(rawEvents.results).map((
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
parentId: { global: e.parentIdGlobal, local: 0 },
|
|
174
|
+
const events = Schema.decodeUnknownSync(Schema.Array(mutationLogTable.schema))(rawEvents.results).map(({ createdAt, ...mutationEventEncoded }) => ({
|
|
175
|
+
mutationEventEncoded,
|
|
176
|
+
metadata: Option.some({ createdAt }),
|
|
152
177
|
}));
|
|
153
178
|
return events;
|
|
154
179
|
};
|
|
155
|
-
const appendEvent = async (event) => {
|
|
156
|
-
const sql = `INSERT INTO ${dbName} (
|
|
180
|
+
const appendEvent = async (event, createdAt) => {
|
|
181
|
+
const sql = `INSERT INTO ${dbName} (id, parentId, args, mutation, createdAt) VALUES (?, ?, ?, ?, ?)`;
|
|
157
182
|
await env.DB.prepare(sql)
|
|
158
|
-
.bind(event.id
|
|
183
|
+
.bind(event.id, event.parentId, JSON.stringify(event.args), event.mutation, createdAt)
|
|
159
184
|
.run();
|
|
160
185
|
};
|
|
161
186
|
const resetRoom = async () => {
|
|
162
187
|
await ctx.storage.deleteAll();
|
|
163
188
|
};
|
|
164
|
-
return { getLatestEvent, getEvents, appendEvent, resetRoom };
|
|
189
|
+
return { dbName, getLatestEvent, getEvents, appendEvent, resetRoom };
|
|
190
|
+
};
|
|
191
|
+
const getStoreId = (request) => {
|
|
192
|
+
const url = new URL(request.url);
|
|
193
|
+
const searchParams = url.searchParams;
|
|
194
|
+
const storeId = searchParams.get('storeId');
|
|
195
|
+
if (storeId === null) {
|
|
196
|
+
throw new Error('storeId search param is required');
|
|
197
|
+
}
|
|
198
|
+
return storeId;
|
|
165
199
|
};
|
|
200
|
+
const toValidTableName = (str) => str.replaceAll(/[^a-zA-Z0-9]/g, '_');
|
|
166
201
|
//# sourceMappingURL=durable-object.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"durable-object.js","sourceRoot":"","sources":["../../src/cf-worker/durable-object.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"durable-object.js","sourceRoot":"","sources":["../../src/cf-worker/durable-object.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAsB,MAAM,0BAA0B,CAAA;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAW5C,MAAM,qBAAqB,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC,CAAA;AACnG,MAAM,qBAAqB,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC,CAAA;AACnG,MAAM,qBAAqB,GAAG,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC,CAAA;AAE5G,8EAA8E;AAC9E,MAAM,CAAC,MAAM,gBAAgB,GAAG,QAAQ,CAAC,KAAK,CAAC,UAAU,EAAE;IACzD,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;IACzE,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;IAC7D,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IAC3B,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IAC7D,mEAAmE;IACnE,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;CAC7B,CAAC,CAAA;AAEF,MAAM,yBAAyB,GAAG,MAAM,CAAC,SAAS,CAChD,MAAM,CAAC,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM;CACvB,CAAC,CACH,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAA;AAW3C,MAAM,CAAC,MAAM,iBAAiB,GAA2B,CAAC,OAAO,EAAE,EAAE;IACnE,OAAO,MAAM,mBAAoB,SAAQ,aAAkB;QACzD,YAAY,GAAuB,EAAE,GAAQ;YAC3C,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;QACjB,CAAC;QAED,KAAK,GAAG,KAAK,EAAE,OAAgB,EAAE,EAAE,CACjC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC;YACxB,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,CAAA;YACnC,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;YAExD,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,aAAa,EAAE,CAAA;YAEpD,mHAAmH;YACnH,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;YAErF,8FAA8F;YAE9F,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,CAAA;YAEhC,IAAI,CAAC,GAAG,CAAC,wBAAwB,CAC/B,IAAI,4BAA4B,CAC9B,qBAAqB,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,EACjE,qBAAqB,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,CAClE,CACF,CAAA;YAED,MAAM,OAAO,GAAG,cAAc,CAAC,gBAAgB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;YAC9D,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,8BAA8B,OAAO,CAAC,MAAM,KAAK,OAAO,UAAU,CAAC,CAAA;YAEpF,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;gBACxB,MAAM,EAAE,GAAG;gBACX,SAAS,EAAE,MAAM;aAClB,CAAC,CAAA;QACJ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,UAAU,CAAC,CAAA;QAEtD,gBAAgB,GAAG,CAAC,EAAmB,EAAE,OAA6B,EAAE,EAAE,CACxE,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC;YACxB,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAA;YAExD,IAAI,iBAAiB,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACtC,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAA;gBACjE,OAAM;YACR,CAAC;YAED,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,EAAE,CAAC,qBAAqB,EAAE,CAAC,CAAA;YAC/F,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;YAExD,MAAM,cAAc,GAAG,iBAAiB,CAAC,KAAK,CAAA;YAC9C,MAAM,SAAS,GAAG,cAAc,CAAC,SAAS,CAAA;YAE1C,IAAI,CAAC;gBACH,QAAQ,cAAc,CAAC,IAAI,EAAE,CAAC;oBAC5B,KAAK,mBAAmB,CAAC,CAAC,CAAC;wBACzB,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;4BACpB,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,MAAO,CAAC,cAAc,CAAC,CAAC,CAAA;wBAC7D,CAAC;wBAED,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAA;wBACpC,MAAM,UAAU,GAAG,GAAG,CAAA;wBAEtB,qBAAqB;wBACrB,MAAM,eAAe,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;wBAErF,0GAA0G;wBAC1G,OAAO,IAAI,EAAE,CAAC;4BACZ,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;4BAEpD,EAAE,CAAC,IAAI,CACL,qBAAqB,CACnB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CACjF,CACF,CAAA;4BAED,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gCACjC,MAAK;4BACP,CAAC;wBACH,CAAC;wBAED,MAAK;oBACP,CAAC;oBACD,KAAK,mBAAmB,CAAC,CAAC,CAAC;wBACzB,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;4BACpB,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,MAAO,CAAC,cAAc,CAAC,CAAC,CAAA;wBAC7D,CAAC;wBAED,6FAA6F;wBAC7F,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAA;wBACzE,MAAM,gBAAgB,GAAG,WAAW,EAAE,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAA;wBAE/D,IAAI,CAAC,GAAG,CAAC,CAAA;wBACT,KAAK,MAAM,oBAAoB,IAAI,cAAc,CAAC,KAAK,EAAE,CAAC;4BACxD,IAAI,oBAAoB,CAAC,QAAQ,KAAK,gBAAgB,GAAG,CAAC,EAAE,CAAC;gCAC3D,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC;oCAC/B,OAAO,EAAE,+BAA+B,oBAAoB,CAAC,QAAQ,iBAAiB,gBAAgB,EAAE;oCACxG,SAAS;iCACV,CAAC,CAAA;gCAEF,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;gCAEjD,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAA;gCACnC,OAAM;4BACR,CAAC;4BAED,uCAAuC;4BAEvC,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;4BAE1C,6EAA6E;4BAC7E,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAA;4BAEzE,EAAE,CAAC,IAAI,CACL,qBAAqB,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,oBAAoB,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,CAClG,CAAA;4BAED,4FAA4F;4BAE5F,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAA;4BAEjD,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gCAChC,MAAM,gBAAgB,GAAG,qBAAqB;gCAC5C,6BAA6B;gCAC7B,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC;oCAC3B,oBAAoB;oCACpB,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC;iCACrC,CAAC,CACH,CAAA;gCAED,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;oCACpC,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;oCACrE,qBAAqB;oCACrB,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;oCAC3B,IAAI;gCACN,CAAC;4BACH,CAAC;4BAED,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,CAAA;4BAEzC,CAAC,EAAE,CAAA;wBACL,CAAC;wBAED,MAAK;oBACP,CAAC;oBACD,KAAK,6BAA6B,CAAC,CAAC,CAAC;wBACnC,IAAI,cAAc,CAAC,WAAW,KAAK,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;4BACzD,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAA;4BACpG,OAAM;wBACR,CAAC;wBAED,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAA;wBAChD,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAA;wBAE/E,MAAK;oBACP,CAAC;oBACD,KAAK,wBAAwB,CAAC,CAAC,CAAC;wBAC9B,IAAI,cAAc,CAAC,WAAW,KAAK,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;4BACzD,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAA;4BACpG,OAAM;wBACR,CAAC;wBAED,EAAE,CAAC,IAAI,CACL,qBAAqB,CACnB,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,eAAe,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,CAC9F,CACF,CAAA;wBAED,MAAK;oBACP,CAAC;oBACD,OAAO,CAAC,CAAC,CAAC;wBACR,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,cAAc,CAAC,CAAA;wBACpD,OAAO,iBAAiB,EAAE,CAAA;oBAC5B,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAA;YAC7F,CAAC;QACH,CAAC,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,QAAQ,CAAC,oDAAoD,CAAC,EACrE,MAAM,CAAC,iBAAiB,EACxB,MAAM,CAAC,mBAAmB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAC1C,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAC7B,MAAM,CAAC,UAAU,CAClB,CAAA;QAEH,cAAc,GAAG,KAAK,EAAE,EAAmB,EAAE,IAAY,EAAE,OAAe,EAAE,SAAkB,EAAE,EAAE;YAChG,6FAA6F;YAC7F,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,qCAAqC,CAAC,CAAA;QACvD,CAAC,CAAA;KACF,CAAA;AACH,CAAC,CAAA;AAcD,MAAM,WAAW,GAAG,CAAC,GAAuB,EAAE,GAAQ,EAAE,OAAe,EAAe,EAAE;IACtF,MAAM,MAAM,GAAG,gBAAgB,0BAA0B,IAAI,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAA;IAExF,MAAM,cAAc,GAAG,KAAK,IAAyD,EAAE;QACrF,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,iBAAiB,MAAM,2BAA2B,CAAC,CAAC,GAAG,EAAE,CAAA;QAChG,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;QAClC,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;QAEjG,OAAO,MAAM,CAAC,CAAC,CAAC,CAAA;IAClB,CAAC,CAAA;IAED,MAAM,SAAS,GAAG,KAAK,EACrB,MAA0B,EAG1B,EAAE;QACF,MAAM,WAAW,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,MAAM,EAAE,CAAA;QACtE,MAAM,GAAG,GAAG,iBAAiB,MAAM,IAAI,WAAW,kBAAkB,CAAA;QACpE,gDAAgD;QAChD,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAA;QACjD,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;QAClC,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,CACnG,CAAC,EAAE,SAAS,EAAE,GAAG,oBAAoB,EAAE,EAAE,EAAE,CAAC,CAAC;YAC3C,oBAAoB;YACpB,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC;SACrC,CAAC,CACH,CAAA;QACD,OAAO,MAAM,CAAA;IACf,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,KAAK,EAAE,KAAqC,EAAE,SAAiB,EAAE,EAAE;QACrF,MAAM,GAAG,GAAG,eAAe,MAAM,mEAAmE,CAAA;QACpG,MAAM,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;aACtB,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC;aACrF,GAAG,EAAE,CAAA;IACV,CAAC,CAAA;IAED,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;QAC3B,MAAM,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,CAAA;IAC/B,CAAC,CAAA;IAED,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,CAAA;AACtE,CAAC,CAAA;AAED,MAAM,UAAU,GAAG,CAAC,OAAgB,EAAE,EAAE;IACtC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAChC,MAAM,YAAY,GAAG,GAAG,CAAC,YAAY,CAAA;IACrC,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IAC3C,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAA;IACrD,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,gBAAgB,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,eAAe,EAAE,GAAG,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/cf-worker/mod.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,aAAa,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/cf-worker/mod.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,aAAa,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/cf-worker/worker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAA;AAE9C,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,gBAAgB,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;CAChF,CAAA;AAED,eAAO,MAAM,UAAU,QAAO,QAgC7B,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const makeWorker = () => {
|
|
2
|
+
return {
|
|
3
|
+
fetch: async (request, env, _ctx) => {
|
|
4
|
+
const url = new URL(request.url);
|
|
5
|
+
const searchParams = url.searchParams;
|
|
6
|
+
const storeId = searchParams.get('storeId');
|
|
7
|
+
if (storeId === null) {
|
|
8
|
+
return new Response('storeId search param is required', { status: 400 });
|
|
9
|
+
}
|
|
10
|
+
const id = env.WEBSOCKET_SERVER.idFromName(storeId);
|
|
11
|
+
const durableObject = env.WEBSOCKET_SERVER.get(id);
|
|
12
|
+
if (url.pathname.endsWith('/websocket')) {
|
|
13
|
+
const upgradeHeader = request.headers.get('Upgrade');
|
|
14
|
+
if (!upgradeHeader || upgradeHeader !== 'websocket') {
|
|
15
|
+
return new Response('Durable Object expected Upgrade: websocket', { status: 426 });
|
|
16
|
+
}
|
|
17
|
+
return durableObject.fetch(request);
|
|
18
|
+
}
|
|
19
|
+
return new Response(null, {
|
|
20
|
+
status: 400,
|
|
21
|
+
statusText: 'Bad Request',
|
|
22
|
+
headers: {
|
|
23
|
+
'Content-Type': 'text/plain',
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=worker.js.map
|
|
@@ -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,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;YAE3C,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrB,OAAO,IAAI,QAAQ,CAAC,kCAAkC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;YAC1E,CAAC;YAED,MAAM,EAAE,GAAG,GAAG,CAAC,gBAAgB,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;YACnD,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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * as WSMessage from './ws-message-types.js';
|
|
2
|
-
//# sourceMappingURL=
|
|
2
|
+
//# sourceMappingURL=mod.d.ts.map
|
|
@@ -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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * as WSMessage from './ws-message-types.js';
|
|
2
|
-
//# sourceMappingURL=
|
|
2
|
+
//# sourceMappingURL=mod.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/common/mod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAA"}
|