Skip to content

Commit 50d92bd

Browse files
authored
refactor: server adaptors interface (#23)
* refactor: server adaptors interface * fix: always free wasm
1 parent 37f3a90 commit 50d92bd

File tree

8 files changed

+82
-361
lines changed

8 files changed

+82
-361
lines changed

packages/loro-adaptors/src/server/server-flock-adaptor.ts

Lines changed: 4 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ import {
77
CrdtType,
88
JoinResponseOk,
99
MessageType,
10-
Permission,
11-
UpdateError,
12-
UpdateErrorCode,
1310
} from "loro-protocol";
1411
import type { CrdtServerAdaptor } from "../types";
1512
const encoder = new TextEncoder();
@@ -108,7 +105,6 @@ export class FlockServerAdaptor implements CrdtServerAdaptor {
108105
handleJoinRequest(
109106
documentData: Uint8Array,
110107
clientVersion: Uint8Array,
111-
permission: Permission,
112108
): {
113109
response: JoinResponseOk;
114110
updates?: Uint8Array[];
@@ -131,7 +127,7 @@ export class FlockServerAdaptor implements CrdtServerAdaptor {
131127
type: MessageType.JoinResponseOk,
132128
crdt: this.crdtType,
133129
roomId: "",
134-
permission,
130+
permission: "write",
135131
version: serverVersion,
136132
};
137133

@@ -141,25 +137,7 @@ export class FlockServerAdaptor implements CrdtServerAdaptor {
141137
applyUpdates(
142138
documentData: Uint8Array,
143139
updates: Uint8Array[],
144-
permission: Permission,
145-
): {
146-
success: boolean;
147-
newDocumentData?: Uint8Array;
148-
error?: UpdateError;
149-
broadcastUpdates?: Uint8Array[];
150-
} {
151-
if (permission === "read") {
152-
return {
153-
success: false,
154-
error: {
155-
type: MessageType.UpdateError,
156-
crdt: this.crdtType,
157-
roomId: "",
158-
code: UpdateErrorCode.PermissionDenied,
159-
message: "Read-only permission, cannot apply updates",
160-
},
161-
};
162-
}
140+
): Uint8Array {
163141

164142
const flock = new Flock();
165143
const broadcastUpdates: Uint8Array[] = [];
@@ -180,24 +158,9 @@ export class FlockServerAdaptor implements CrdtServerAdaptor {
180158
}
181159
}
182160

183-
const newDocumentData = serializeBundle(exportBundle(flock));
184-
return {
185-
success: true,
186-
newDocumentData,
187-
broadcastUpdates:
188-
broadcastUpdates.length > 0 ? broadcastUpdates : undefined,
189-
};
161+
return serializeBundle(exportBundle(flock));
190162
} catch (error) {
191-
return {
192-
success: false,
193-
error: {
194-
type: MessageType.UpdateError,
195-
crdt: this.crdtType,
196-
roomId: "",
197-
code: UpdateErrorCode.InvalidUpdate,
198-
message: error instanceof Error ? error.message : "Invalid update",
199-
},
200-
};
163+
throw new Error(error instanceof Error ? error.message : "Invalid update", { cause: error });
201164
}
202165
}
203166

packages/loro-adaptors/src/server/server-loro-adaptor.ts

Lines changed: 5 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
import { LoroDoc, VersionVector } from "loro-crdt";
22
import {
33
CrdtType,
4-
Permission,
54
MessageType,
65
JoinResponseOk,
7-
UpdateError,
8-
UpdateErrorCode,
96
} from "loro-protocol";
107
import type { CrdtServerAdaptor } from "../types";
118

@@ -22,7 +19,6 @@ export class LoroServerAdaptor implements CrdtServerAdaptor {
2219
handleJoinRequest(
2320
documentData: Uint8Array,
2421
clientVersion: Uint8Array,
25-
permission: Permission
2622
): {
2723
response: JoinResponseOk;
2824
updates?: Uint8Array[];
@@ -52,7 +48,7 @@ export class LoroServerAdaptor implements CrdtServerAdaptor {
5248
type: MessageType.JoinResponseOk,
5349
crdt: this.crdtType,
5450
roomId: "",
55-
permission,
51+
permission: "write",
5652
version: serverVersion.encode(),
5753
};
5854

@@ -66,60 +62,20 @@ export class LoroServerAdaptor implements CrdtServerAdaptor {
6662
applyUpdates(
6763
documentData: Uint8Array,
6864
updates: Uint8Array[],
69-
permission: Permission
70-
): {
71-
success: boolean;
72-
newDocumentData?: Uint8Array;
73-
error?: UpdateError;
74-
broadcastUpdates?: Uint8Array[];
75-
} {
76-
if (permission === "read") {
77-
return {
78-
success: false,
79-
error: {
80-
type: MessageType.UpdateError,
81-
crdt: this.crdtType,
82-
roomId: "",
83-
code: UpdateErrorCode.PermissionDenied,
84-
message: "Read-only permission, cannot apply updates",
85-
},
86-
};
87-
}
65+
): Uint8Array {
8866
const doc = new LoroDoc();
89-
const broadcastUpdates: Uint8Array[] = [];
90-
9167
try {
9268
if (documentData.length > 0) {
9369
doc.import(documentData);
9470
}
9571
for (const update of updates) {
9672
if (update.length > 0) {
97-
const importResult = doc.import(update);
98-
if (importResult.success) {
99-
broadcastUpdates.push(update);
100-
}
73+
doc.import(update);
10174
}
10275
}
103-
104-
const newDocumentData = doc.export({ mode: "snapshot" });
105-
106-
return {
107-
success: true,
108-
newDocumentData,
109-
broadcastUpdates:
110-
broadcastUpdates.length > 0 ? broadcastUpdates : undefined,
111-
};
76+
return doc.export({ mode: "snapshot" });
11277
} catch (error) {
113-
return {
114-
success: false,
115-
error: {
116-
type: MessageType.UpdateError,
117-
crdt: this.crdtType,
118-
roomId: "",
119-
code: UpdateErrorCode.InvalidUpdate,
120-
message: error instanceof Error ? error.message : "Invalid update",
121-
},
122-
};
78+
throw new Error(error instanceof Error ? error.message : "Invalid update", { cause: error });
12379
} finally {
12480
doc.free();
12581
}

packages/loro-adaptors/src/server/server-loro-ephemeral-adaptor.ts

Lines changed: 4 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
import { EphemeralStore } from "loro-crdt";
22
import {
33
CrdtType,
4-
Permission,
54
MessageType,
65
JoinResponseOk,
7-
UpdateError,
8-
UpdateErrorCode,
96
} from "loro-protocol";
107
import type { CrdtServerAdaptor } from "../types";
118

@@ -33,7 +30,6 @@ export class LoroEphemeralServerAdaptor implements CrdtServerAdaptor {
3330
handleJoinRequest(
3431
documentData: Uint8Array,
3532
_clientVersion: Uint8Array,
36-
permission: Permission
3733
): {
3834
response: JoinResponseOk;
3935
updates?: Uint8Array[];
@@ -42,7 +38,7 @@ export class LoroEphemeralServerAdaptor implements CrdtServerAdaptor {
4238
type: MessageType.JoinResponseOk,
4339
crdt: this.crdtType,
4440
roomId: "",
45-
permission,
41+
permission: "write",
4642
version: new Uint8Array(),
4743
};
4844

@@ -53,26 +49,7 @@ export class LoroEphemeralServerAdaptor implements CrdtServerAdaptor {
5349
applyUpdates(
5450
documentData: Uint8Array,
5551
updates: Uint8Array[],
56-
permission: Permission
57-
): {
58-
success: boolean;
59-
newDocumentData?: Uint8Array;
60-
error?: UpdateError;
61-
broadcastUpdates?: Uint8Array[];
62-
} {
63-
if (permission === "read") {
64-
return {
65-
success: false,
66-
error: {
67-
type: MessageType.UpdateError,
68-
crdt: this.crdtType,
69-
roomId: "",
70-
code: UpdateErrorCode.PermissionDenied,
71-
message: "Read-only permission, cannot apply updates",
72-
},
73-
};
74-
}
75-
52+
): Uint8Array {
7653
const store = new EphemeralStore(this.timeout);
7754
const broadcastUpdates: Uint8Array[] = [];
7855

@@ -89,23 +66,9 @@ export class LoroEphemeralServerAdaptor implements CrdtServerAdaptor {
8966

9067
const newDocumentData = store.encodeAll();
9168

92-
return {
93-
success: true,
94-
newDocumentData,
95-
broadcastUpdates:
96-
broadcastUpdates.length > 0 ? broadcastUpdates : undefined,
97-
};
69+
return newDocumentData;
9870
} catch (error) {
99-
return {
100-
success: false,
101-
error: {
102-
type: MessageType.UpdateError,
103-
crdt: this.crdtType,
104-
roomId: "",
105-
code: UpdateErrorCode.InvalidUpdate,
106-
message: error instanceof Error ? error.message : "Invalid update",
107-
},
108-
};
71+
throw new Error(error instanceof Error ? error.message : "Invalid update", { cause: error });
10972
} finally {
11073
store.destroy();
11174
store.inner.free();
@@ -126,7 +89,6 @@ export class LoroEphemeralServerAdaptor implements CrdtServerAdaptor {
12689
try {
12790
return store.encodeAll();
12891
} finally {
129-
store.destroy();
13092
store.inner.free();
13193
}
13294
}

packages/loro-adaptors/src/server/server-loro-persistent-store-adaptor.ts

Lines changed: 11 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
import { EphemeralStore } from "loro-crdt";
22
import {
33
CrdtType,
4-
Permission,
54
MessageType,
65
JoinResponseOk,
7-
UpdateError,
8-
UpdateErrorCode,
96
} from "loro-protocol";
107
import type { CrdtServerAdaptor } from "../types";
118

@@ -33,16 +30,12 @@ export class LoroPersistentStoreServerAdaptor implements CrdtServerAdaptor {
3330
handleJoinRequest(
3431
documentData: Uint8Array,
3532
_clientVersion: Uint8Array,
36-
permission: Permission
37-
): {
38-
response: JoinResponseOk;
39-
updates?: Uint8Array[];
40-
} {
33+
): { response: JoinResponseOk, updates?: Uint8Array[] } {
4134
const response: JoinResponseOk = {
4235
type: MessageType.JoinResponseOk,
4336
crdt: this.crdtType,
4437
roomId: "",
45-
permission,
38+
permission: "write",
4639
version: new Uint8Array(),
4740
};
4841

@@ -53,62 +46,23 @@ export class LoroPersistentStoreServerAdaptor implements CrdtServerAdaptor {
5346
applyUpdates(
5447
documentData: Uint8Array,
5548
updates: Uint8Array[],
56-
permission: Permission
57-
): {
58-
success: boolean;
59-
newDocumentData?: Uint8Array;
60-
error?: UpdateError;
61-
broadcastUpdates?: Uint8Array[];
62-
} {
63-
if (permission === "read") {
64-
return {
65-
success: false,
66-
error: {
67-
type: MessageType.UpdateError,
68-
crdt: this.crdtType,
69-
roomId: "",
70-
code: UpdateErrorCode.PermissionDenied,
71-
message: "Read-only permission, cannot apply updates",
72-
},
73-
};
74-
}
75-
49+
): Uint8Array {
7650
const store = new EphemeralStore(this.timeout);
77-
const broadcastUpdates: Uint8Array[] = [];
78-
7951
try {
52+
8053
if (documentData.length > 0) {
8154
store.apply(documentData);
8255
}
8356
for (const update of updates) {
8457
if (update.length > 0) {
8558
store.apply(update);
86-
broadcastUpdates.push(update);
8759
}
8860
}
8961

9062
const newDocumentData = store.encodeAll();
91-
92-
return {
93-
success: true,
94-
newDocumentData,
95-
broadcastUpdates:
96-
broadcastUpdates.length > 0 ? broadcastUpdates : undefined,
97-
};
98-
} catch (error) {
99-
return {
100-
success: false,
101-
error: {
102-
type: MessageType.UpdateError,
103-
crdt: this.crdtType,
104-
roomId: "",
105-
code: UpdateErrorCode.InvalidUpdate,
106-
message: error instanceof Error ? error.message : "Invalid update",
107-
},
108-
};
63+
return newDocumentData;
10964
} finally {
110-
store.destroy();
111-
store.inner.free();
65+
store.inner.free()
11266
}
11367
}
11468

@@ -118,12 +72,12 @@ export class LoroPersistentStoreServerAdaptor implements CrdtServerAdaptor {
11872

11973
merge(documents: Uint8Array[]): Uint8Array {
12074
const store = new EphemeralStore(this.timeout);
121-
for (const data of documents) {
122-
if (data.length > 0) {
123-
store.apply(data);
124-
}
125-
}
12675
try {
76+
for (const data of documents) {
77+
if (data.length > 0) {
78+
store.apply(data);
79+
}
80+
}
12781
return store.encodeAll();
12882
} finally {
12983
store.destroy();

0 commit comments

Comments
 (0)