@liveblocks/server 1.2.0 → 1.2.1

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/index.cjs CHANGED
@@ -20,8 +20,131 @@ var _core = require('@liveblocks/core');
20
20
 
21
21
 
22
22
 
23
+
24
+
23
25
  var _decoders = require('decoders');
24
26
 
27
+ // src/protocol/feedMessages.ts
28
+ var FeedMsgCode = {
29
+ // Server → client (50x)
30
+ FEEDS_LIST: 500,
31
+ FEEDS_ADDED: 501,
32
+ FEEDS_UPDATED: 502,
33
+ FEED_DELETED: 503,
34
+ FEED_MESSAGES_LIST: 504,
35
+ FEED_MESSAGES_ADDED: 505,
36
+ FEED_MESSAGES_UPDATED: 506,
37
+ FEED_MESSAGES_DELETED: 507,
38
+ FEED_REQUEST_FAILED: 508,
39
+ // Client → server (51x)
40
+ FETCH_FEEDS: 510,
41
+ FETCH_FEED_MESSAGES: 511,
42
+ ADD_FEED: 512,
43
+ UPDATE_FEED: 513,
44
+ DELETE_FEED: 514,
45
+ ADD_FEED_MESSAGE: 515,
46
+ UPDATE_FEED_MESSAGE: 516,
47
+ DELETE_FEED_MESSAGE: 517
48
+ };
49
+ var FeedRequestErrorCode = {
50
+ INTERNAL: "INTERNAL",
51
+ FEED_ALREADY_EXISTS: "FEED_ALREADY_EXISTS",
52
+ FEED_NOT_FOUND: "FEED_NOT_FOUND",
53
+ FEED_MESSAGE_NOT_FOUND: "FEED_MESSAGE_NOT_FOUND"
54
+ };
55
+
56
+ // src/protocol/feedErrors.ts
57
+ function feedRequestFailed(requestId, code, reason) {
58
+ return {
59
+ type: FeedMsgCode.FEED_REQUEST_FAILED,
60
+ requestId: _nullishCoalesce(requestId, () => ( "")),
61
+ code,
62
+ reason
63
+ };
64
+ }
65
+ function mapFeedError(err) {
66
+ if (!(err instanceof Error)) {
67
+ return { code: FeedRequestErrorCode.INTERNAL };
68
+ }
69
+ const m = err.message;
70
+ if (m.includes("already exists")) {
71
+ return { code: FeedRequestErrorCode.FEED_ALREADY_EXISTS, reason: m };
72
+ }
73
+ if (m.includes("Feed message") && m.includes("not found")) {
74
+ return { code: FeedRequestErrorCode.FEED_MESSAGE_NOT_FOUND, reason: m };
75
+ }
76
+ if (m.includes("not found")) {
77
+ return { code: FeedRequestErrorCode.FEED_NOT_FOUND, reason: m };
78
+ }
79
+ return { code: FeedRequestErrorCode.INTERNAL, reason: m };
80
+ }
81
+ function feedFailureServerMsg(requestId, err) {
82
+ const mapped = mapFeedError(err);
83
+ return feedRequestFailed(requestId, mapped.code, mapped.reason);
84
+ }
85
+
86
+ // src/protocol/ProtocolVersion.ts
87
+
88
+ var ProtocolVersion = /* @__PURE__ */ ((ProtocolVersion2) => {
89
+ ProtocolVersion2[ProtocolVersion2["V7"] = 7] = "V7";
90
+ ProtocolVersion2[ProtocolVersion2["V8"] = 8] = "V8";
91
+ return ProtocolVersion2;
92
+ })(ProtocolVersion || {});
93
+ var protocolVersionDecoder = _decoders.enum_.call(void 0, ProtocolVersion).describe(
94
+ "Unsupported protocol version"
95
+ );
96
+
97
+ // src/decoders/feedMetadata.ts
98
+
99
+
100
+
101
+
102
+
103
+
104
+
105
+
106
+
107
+
108
+
109
+
110
+ var MAX_METADATA_COUNT = 50;
111
+ var MAX_METADATA_VALUE_LIST_LENGTH = 50;
112
+ var feedMetadataIdDecoder = _decoders.sized.call(void 0, _decoders.identifier, { min: 1, max: 40 });
113
+ var metadataStringValue = _decoders.sized.call(void 0, _decoders.string, { max: 256 });
114
+ function createRoomMetadataValueDecoder() {
115
+ return _decoders.select.call(void 0,
116
+ _decoders.either.call(void 0, _decoders.string, _decoders.poja).describe("Must be string or string[]"),
117
+ (x) => typeof x === "string" ? metadataStringValue : _decoders.array.call(void 0, metadataStringValue).refine(
118
+ (value) => value.length <= MAX_METADATA_VALUE_LIST_LENGTH,
119
+ `Must be at most ${MAX_METADATA_VALUE_LIST_LENGTH} items`
120
+ )
121
+ );
122
+ }
123
+ var roomMetadataValueDecoder = createRoomMetadataValueDecoder();
124
+ var feedMetadataNullableValueDecoder = _decoders.nullable.call(void 0, roomMetadataValueDecoder);
125
+ var feedMetadataRecordForCreate = _decoders.record.call(void 0,
126
+ feedMetadataIdDecoder,
127
+ roomMetadataValueDecoder
128
+ ).refine(
129
+ (value) => Object.keys(value).length <= MAX_METADATA_COUNT,
130
+ `Must be at most ${MAX_METADATA_COUNT} items`
131
+ );
132
+ var optionalFeedMetadataDecoder = _decoders.optional.call(void 0, feedMetadataRecordForCreate);
133
+ var feedMetadataUpdateDecoder = _decoders.record.call(void 0,
134
+ feedMetadataIdDecoder,
135
+ feedMetadataNullableValueDecoder
136
+ );
137
+ var feedMetadataRecordForFilter = _decoders.record.call(void 0,
138
+ feedMetadataIdDecoder,
139
+ feedMetadataNullableValueDecoder
140
+ ).refine(
141
+ (value) => Object.keys(value).length <= MAX_METADATA_COUNT,
142
+ `Must be at most ${MAX_METADATA_COUNT} items`
143
+ );
144
+ var fetchFeedsMetadataFilterDecoder = _decoders.optional.call(void 0,
145
+ feedMetadataRecordForFilter
146
+ );
147
+
25
148
  // src/decoders/jsonYolo.ts
26
149
 
27
150
  var jsonYolo = _decoders.unknown;
@@ -141,13 +264,77 @@ var updateYDocClientMsg = _decoders.object.call(void 0, {
141
264
  // Don't specify to update the root doc
142
265
  v2: _decoders.optional.call(void 0, _decoders.boolean)
143
266
  });
267
+ var fetchFeedsClientMsg = _decoders.object.call(void 0, {
268
+ type: _decoders.constant.call(void 0, FeedMsgCode.FETCH_FEEDS),
269
+ requestId: _decoders.string,
270
+ cursor: _decoders.optional.call(void 0, _decoders.string),
271
+ since: _decoders.optional.call(void 0, _decoders.number),
272
+ limit: _decoders.optional.call(void 0, _decoders.number),
273
+ metadata: fetchFeedsMetadataFilterDecoder
274
+ });
275
+ var fetchFeedMessagesClientMsg = _decoders.object.call(void 0, {
276
+ type: _decoders.constant.call(void 0, FeedMsgCode.FETCH_FEED_MESSAGES),
277
+ requestId: _decoders.string,
278
+ feedId: _decoders.nonEmptyString,
279
+ cursor: _decoders.optional.call(void 0, _decoders.string),
280
+ since: _decoders.optional.call(void 0, _decoders.number),
281
+ limit: _decoders.optional.call(void 0, _decoders.number)
282
+ });
283
+ var addFeedClientMsg = _decoders.object.call(void 0, {
284
+ type: _decoders.constant.call(void 0, FeedMsgCode.ADD_FEED),
285
+ feedId: _decoders.string,
286
+ metadata: optionalFeedMetadataDecoder,
287
+ timestamp: _decoders.optional.call(void 0, _decoders.number),
288
+ requestId: _decoders.optional.call(void 0, _decoders.string)
289
+ });
290
+ var updateFeedClientMsg = _decoders.object.call(void 0, {
291
+ type: _decoders.constant.call(void 0, FeedMsgCode.UPDATE_FEED),
292
+ feedId: _decoders.string,
293
+ metadata: feedMetadataUpdateDecoder,
294
+ requestId: _decoders.optional.call(void 0, _decoders.string)
295
+ });
296
+ var deleteFeedClientMsg = _decoders.object.call(void 0, {
297
+ type: _decoders.constant.call(void 0, FeedMsgCode.DELETE_FEED),
298
+ feedId: _decoders.string,
299
+ requestId: _decoders.optional.call(void 0, _decoders.string)
300
+ });
301
+ var addFeedMessageClientMsg = _decoders.object.call(void 0, {
302
+ type: _decoders.constant.call(void 0, FeedMsgCode.ADD_FEED_MESSAGE),
303
+ feedId: _decoders.string,
304
+ data: _decoders.jsonObject,
305
+ id: _decoders.optional.call(void 0, _decoders.string),
306
+ timestamp: _decoders.optional.call(void 0, _decoders.number),
307
+ requestId: _decoders.optional.call(void 0, _decoders.string)
308
+ });
309
+ var updateFeedMessageClientMsg = _decoders.object.call(void 0, {
310
+ type: _decoders.constant.call(void 0, FeedMsgCode.UPDATE_FEED_MESSAGE),
311
+ feedId: _decoders.string,
312
+ messageId: _decoders.string,
313
+ data: _decoders.jsonObject,
314
+ timestamp: _decoders.optional.call(void 0, _decoders.number),
315
+ requestId: _decoders.optional.call(void 0, _decoders.string)
316
+ });
317
+ var deleteFeedMessageClientMsg = _decoders.object.call(void 0, {
318
+ type: _decoders.constant.call(void 0, FeedMsgCode.DELETE_FEED_MESSAGE),
319
+ feedId: _decoders.string,
320
+ messageId: _decoders.string,
321
+ requestId: _decoders.optional.call(void 0, _decoders.string)
322
+ });
144
323
  var clientMsgDecoder = _decoders.taggedUnion.call(void 0, "type", {
145
324
  [_core.ClientMsgCode.UPDATE_PRESENCE]: updatePresenceClientMsg,
146
325
  [_core.ClientMsgCode.BROADCAST_EVENT]: broadcastEventClientMsg,
147
326
  [_core.ClientMsgCode.FETCH_STORAGE]: fetchStorageClientMsg,
148
327
  [_core.ClientMsgCode.UPDATE_STORAGE]: updateStorageClientMsg,
149
328
  [_core.ClientMsgCode.FETCH_YDOC]: fetchYDocClientMsg,
150
- [_core.ClientMsgCode.UPDATE_YDOC]: updateYDocClientMsg
329
+ [_core.ClientMsgCode.UPDATE_YDOC]: updateYDocClientMsg,
330
+ [FeedMsgCode.FETCH_FEEDS]: fetchFeedsClientMsg,
331
+ [FeedMsgCode.FETCH_FEED_MESSAGES]: fetchFeedMessagesClientMsg,
332
+ [FeedMsgCode.ADD_FEED]: addFeedClientMsg,
333
+ [FeedMsgCode.UPDATE_FEED]: updateFeedClientMsg,
334
+ [FeedMsgCode.DELETE_FEED]: deleteFeedClientMsg,
335
+ [FeedMsgCode.ADD_FEED_MESSAGE]: addFeedMessageClientMsg,
336
+ [FeedMsgCode.UPDATE_FEED_MESSAGE]: updateFeedMessageClientMsg,
337
+ [FeedMsgCode.DELETE_FEED_MESSAGE]: deleteFeedMessageClientMsg
151
338
  }).describe("Must be a valid client message");
152
339
  var transientClientMsgDecoder = _decoders.taggedUnion.call(void 0, "type", {
153
340
  // [ClientMsgCode.UPDATE_PRESENCE]: updatePresenceClientMsg,
@@ -628,17 +815,6 @@ function makeMetadataDB(driver) {
628
815
  };
629
816
  }
630
817
 
631
- // src/protocol/ProtocolVersion.ts
632
-
633
- var ProtocolVersion = /* @__PURE__ */ ((ProtocolVersion2) => {
634
- ProtocolVersion2[ProtocolVersion2["V7"] = 7] = "V7";
635
- ProtocolVersion2[ProtocolVersion2["V8"] = 8] = "V8";
636
- return ProtocolVersion2;
637
- })(ProtocolVersion || {});
638
- var protocolVersionDecoder = _decoders.enum_.call(void 0, ProtocolVersion).describe(
639
- "Unsupported protocol version"
640
- );
641
-
642
818
  // src/Room.ts
643
819
 
644
820
 
@@ -845,16 +1021,21 @@ function hasStaticDataAt(node, key) {
845
1021
  return node.type === _core.CrdtType.OBJECT && Object.prototype.hasOwnProperty.call(node.data, key) && node.data[key] !== void 0;
846
1022
  }
847
1023
  var InMemoryDriver = class {
1024
+ // Key: `${feedId}:${messageId}`
848
1025
  constructor(options) {
849
1026
  __publicField(this, "_nextActor");
850
1027
  __publicField(this, "_nodes");
851
1028
  __publicField(this, "_metadb");
852
1029
  __publicField(this, "_ydb");
853
1030
  __publicField(this, "_leasedSessions");
1031
+ __publicField(this, "_feeds");
1032
+ __publicField(this, "_feedMessages");
854
1033
  this._nodes = /* @__PURE__ */ new Map();
855
1034
  this._metadb = /* @__PURE__ */ new Map();
856
1035
  this._ydb = /* @__PURE__ */ new Map();
857
1036
  this._leasedSessions = /* @__PURE__ */ new Map();
1037
+ this._feeds = /* @__PURE__ */ new Map();
1038
+ this._feedMessages = /* @__PURE__ */ new Map();
858
1039
  this._nextActor = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _35 => _35.initialActor]), () => ( -1));
859
1040
  for (const [key, value] of _nullishCoalesce(_optionalChain([options, 'optionalAccess', _36 => _36.initialNodes]), () => ( []))) {
860
1041
  this._nodes.set(key, value);
@@ -894,6 +1075,180 @@ var InMemoryDriver = class {
894
1075
  takeRowsWritten() {
895
1076
  return 0;
896
1077
  }
1078
+ // ---------------------------------------------------------------------------
1079
+ // Feed APIs
1080
+ // ---------------------------------------------------------------------------
1081
+ async list_feeds(options) {
1082
+ const limit = Math.min(_nullishCoalesce(_optionalChain([options, 'optionalAccess', _37 => _37.limit]), () => ( 20)), 100);
1083
+ const since = _optionalChain([options, 'optionalAccess', _38 => _38.since]);
1084
+ const cursor = _optionalChain([options, 'optionalAccess', _39 => _39.cursor]);
1085
+ const metadata = _optionalChain([options, 'optionalAccess', _40 => _40.metadata]);
1086
+ let feeds = [];
1087
+ for (const [_, feed] of this._feeds.entries()) {
1088
+ if (metadata !== void 0) {
1089
+ const feedMetadata = feed.metadata;
1090
+ let matches = true;
1091
+ for (const [key, value] of Object.entries(metadata)) {
1092
+ if (feedMetadata[key] !== value) {
1093
+ matches = false;
1094
+ break;
1095
+ }
1096
+ }
1097
+ if (!matches) continue;
1098
+ }
1099
+ if (since !== void 0 && feed.createdAt < since) {
1100
+ continue;
1101
+ }
1102
+ feeds.push(feed);
1103
+ }
1104
+ feeds.sort((a, b) => {
1105
+ if (b.createdAt !== a.createdAt) {
1106
+ return b.createdAt - a.createdAt;
1107
+ }
1108
+ return b.feedId.localeCompare(a.feedId);
1109
+ });
1110
+ if (cursor !== void 0) {
1111
+ try {
1112
+ const decoded = JSON.parse(
1113
+ decodeURIComponent(
1114
+ escape(atob(cursor.replace(/-/g, "+").replace(/_/g, "/")))
1115
+ )
1116
+ );
1117
+ const [cursorFeedId, cursorCreatedAt] = decoded;
1118
+ feeds = feeds.filter((s) => {
1119
+ return s.createdAt < cursorCreatedAt || s.createdAt === cursorCreatedAt && s.feedId < cursorFeedId;
1120
+ });
1121
+ } catch (e2) {
1122
+ }
1123
+ }
1124
+ let nextCursor;
1125
+ if (feeds.length > limit) {
1126
+ feeds = feeds.slice(0, limit);
1127
+ const last = feeds[feeds.length - 1];
1128
+ if (last) {
1129
+ const cursorData = [last.feedId, last.createdAt];
1130
+ nextCursor = btoa(
1131
+ unescape(encodeURIComponent(JSON.stringify(cursorData)))
1132
+ ).replace("/", "_").replace("+", "-").replace(/=+$/, "");
1133
+ }
1134
+ }
1135
+ return { feeds, nextCursor };
1136
+ }
1137
+ async get_feed(feedId) {
1138
+ const feed = this._feeds.get(feedId);
1139
+ if (feed === void 0) {
1140
+ return void 0;
1141
+ }
1142
+ return feed;
1143
+ }
1144
+ async create_feed(feed) {
1145
+ if (this._feeds.has(feed.feedId)) {
1146
+ throw new Error(`Feed ${feed.feedId} already exists`);
1147
+ }
1148
+ this._feeds.set(feed.feedId, {
1149
+ feedId: feed.feedId,
1150
+ metadata: feed.metadata,
1151
+ createdAt: feed.createdAt,
1152
+ updatedAt: feed.updatedAt
1153
+ });
1154
+ }
1155
+ async update_feed_metadata(feedId, metadata) {
1156
+ const existing = this._feeds.get(feedId);
1157
+ if (existing === void 0) {
1158
+ throw new Error(`Feed ${feedId} not found`);
1159
+ }
1160
+ this._feeds.set(feedId, {
1161
+ ...existing,
1162
+ metadata
1163
+ });
1164
+ }
1165
+ async delete_feed(feedId) {
1166
+ const messageKeys = [];
1167
+ for (const [key] of this._feedMessages.entries()) {
1168
+ if (key.startsWith(`${feedId}:`)) {
1169
+ messageKeys.push(key);
1170
+ }
1171
+ }
1172
+ for (const key of messageKeys) {
1173
+ this._feedMessages.delete(key);
1174
+ }
1175
+ this._feeds.delete(feedId);
1176
+ }
1177
+ async list_feed_messages(feedId, options) {
1178
+ const limit = Math.min(_nullishCoalesce(_optionalChain([options, 'optionalAccess', _41 => _41.limit]), () => ( 20)), 100);
1179
+ const since = _optionalChain([options, 'optionalAccess', _42 => _42.since]);
1180
+ const cursor = _optionalChain([options, 'optionalAccess', _43 => _43.cursor]);
1181
+ let messages = [];
1182
+ const prefix = `${feedId}:`;
1183
+ for (const [key, message] of this._feedMessages.entries()) {
1184
+ if (key.startsWith(prefix)) {
1185
+ if (since !== void 0 && message.createdAt < since) {
1186
+ continue;
1187
+ }
1188
+ messages.push(message);
1189
+ }
1190
+ }
1191
+ messages.sort((a, b) => {
1192
+ if (b.createdAt !== a.createdAt) {
1193
+ return b.createdAt - a.createdAt;
1194
+ }
1195
+ return b.id.localeCompare(a.id);
1196
+ });
1197
+ if (cursor !== void 0) {
1198
+ try {
1199
+ const decoded = JSON.parse(
1200
+ decodeURIComponent(
1201
+ escape(atob(cursor.replace(/-/g, "+").replace(/_/g, "/")))
1202
+ )
1203
+ );
1204
+ const [cursorMessageId, cursorCreatedAt] = decoded;
1205
+ messages = messages.filter((m) => {
1206
+ return m.createdAt < cursorCreatedAt || m.createdAt === cursorCreatedAt && m.id < cursorMessageId;
1207
+ });
1208
+ } catch (e3) {
1209
+ }
1210
+ }
1211
+ let nextCursor;
1212
+ if (messages.length > limit) {
1213
+ messages = messages.slice(0, limit);
1214
+ const last = messages[messages.length - 1];
1215
+ if (last) {
1216
+ const cursorData = [last.id, last.createdAt];
1217
+ nextCursor = btoa(
1218
+ unescape(encodeURIComponent(JSON.stringify(cursorData)))
1219
+ ).replace("/", "_").replace("+", "-").replace(/=+$/, "");
1220
+ }
1221
+ }
1222
+ return { messages, nextCursor };
1223
+ }
1224
+ async add_feed_message(feedId, message) {
1225
+ const feed = this._feeds.get(feedId);
1226
+ if (feed === void 0) {
1227
+ throw new Error(`Feed ${feedId} not found`);
1228
+ }
1229
+ this._feedMessages.set(`${feedId}:${message.id}`, message);
1230
+ }
1231
+ async update_feed_message(feedId, messageId, data, timestamp) {
1232
+ const key = `${feedId}:${messageId}`;
1233
+ const message = this._feedMessages.get(key);
1234
+ if (message === void 0) {
1235
+ throw new Error(`Feed message ${messageId} not found in feed ${feedId}`);
1236
+ }
1237
+ const effectiveTimestamp = _nullishCoalesce(timestamp, () => ( Date.now()));
1238
+ if (effectiveTimestamp < message.updatedAt) {
1239
+ return message;
1240
+ }
1241
+ const updatedMessage = {
1242
+ ...message,
1243
+ updatedAt: effectiveTimestamp,
1244
+ data
1245
+ };
1246
+ this._feedMessages.set(key, updatedMessage);
1247
+ return updatedMessage;
1248
+ }
1249
+ async delete_feed_message(feedId, messageId) {
1250
+ this._feedMessages.delete(`${feedId}:${messageId}`);
1251
+ }
897
1252
  next_actor() {
898
1253
  return ++this._nextActor;
899
1254
  }
@@ -958,7 +1313,7 @@ var InMemoryDriver = class {
958
1313
  }
959
1314
  async function move_sibling(id, newPos) {
960
1315
  const node = nodes.get(id);
961
- if (_optionalChain([node, 'optionalAccess', _37 => _37.parentId]) === void 0) {
1316
+ if (_optionalChain([node, 'optionalAccess', _44 => _44.parentId]) === void 0) {
962
1317
  return;
963
1318
  }
964
1319
  if (revNodes.has(node.parentId, newPos))
@@ -970,7 +1325,7 @@ var InMemoryDriver = class {
970
1325
  }
971
1326
  async function set_object_data(id, data, allowOverwrite = false) {
972
1327
  const node = nodes.get(id);
973
- if (_optionalChain([node, 'optionalAccess', _38 => _38.type]) !== _core.CrdtType.OBJECT) {
1328
+ if (_optionalChain([node, 'optionalAccess', _45 => _45.type]) !== _core.CrdtType.OBJECT) {
974
1329
  return;
975
1330
  }
976
1331
  for (const key of Object.keys(data)) {
@@ -987,7 +1342,7 @@ var InMemoryDriver = class {
987
1342
  }
988
1343
  function delete_node(id) {
989
1344
  const node = nodes.get(id);
990
- if (_optionalChain([node, 'optionalAccess', _39 => _39.parentId]) === void 0) {
1345
+ if (_optionalChain([node, 'optionalAccess', _46 => _46.parentId]) === void 0) {
991
1346
  return;
992
1347
  }
993
1348
  revNodes.delete(node.parentId, node.parentKey);
@@ -1256,7 +1611,7 @@ var Storage = class {
1256
1611
  }
1257
1612
  return accept(op2);
1258
1613
  } else if (intent === "set") {
1259
- const deletedId = op2.deletedId !== void 0 && op2.deletedId !== op2.id && _optionalChain([this, 'access', _40 => _40.loadedDriver, 'access', _41 => _41.get_node, 'call', _42 => _42(op2.deletedId), 'optionalAccess', _43 => _43.parentId]) === node.parentId ? op2.deletedId : void 0;
1614
+ const deletedId = op2.deletedId !== void 0 && op2.deletedId !== op2.id && _optionalChain([this, 'access', _47 => _47.loadedDriver, 'access', _48 => _48.get_node, 'call', _49 => _49(op2.deletedId), 'optionalAccess', _50 => _50.parentId]) === node.parentId ? op2.deletedId : void 0;
1260
1615
  if (deletedId !== void 0) {
1261
1616
  await this.loadedDriver.delete_node(deletedId);
1262
1617
  }
@@ -1335,10 +1690,10 @@ var Storage = class {
1335
1690
  */
1336
1691
  async moveToPosInList(id, targetKey) {
1337
1692
  const node = this.loadedDriver.get_node(id);
1338
- if (_optionalChain([node, 'optionalAccess', _44 => _44.parentId]) === void 0) {
1693
+ if (_optionalChain([node, 'optionalAccess', _51 => _51.parentId]) === void 0) {
1339
1694
  return;
1340
1695
  }
1341
- if (_optionalChain([this, 'access', _45 => _45.loadedDriver, 'access', _46 => _46.get_node, 'call', _47 => _47(node.parentId), 'optionalAccess', _48 => _48.type]) !== _core.CrdtType.LIST) {
1696
+ if (_optionalChain([this, 'access', _52 => _52.loadedDriver, 'access', _53 => _53.get_node, 'call', _54 => _54(node.parentId), 'optionalAccess', _55 => _55.type]) !== _core.CrdtType.LIST) {
1342
1697
  return;
1343
1698
  }
1344
1699
  if (node.parentKey === targetKey) {
@@ -1448,7 +1803,7 @@ var YjsStorage = class {
1448
1803
  let encodedTargetVector;
1449
1804
  try {
1450
1805
  encodedTargetVector = stateVector.length > 0 ? _jsbase64.Base64.toUint8Array(stateVector) : void 0;
1451
- } catch (e2) {
1806
+ } catch (e4) {
1452
1807
  logger.warn(
1453
1808
  "Could not get update from passed vector, returning all updates"
1454
1809
  );
@@ -1673,13 +2028,14 @@ function isLeasedSessionExpired(leasedSession) {
1673
2028
 
1674
2029
  // src/Room.ts
1675
2030
  var messagesDecoder = _decoders.array.call(void 0, clientMsgDecoder);
2031
+ var ServerMsgCode2 = { ..._core.ServerMsgCode, ...FeedMsgCode };
1676
2032
  var HIGHEST_PROTOCOL_VERSION = Math.max(
1677
2033
  ...Object.values(ProtocolVersion).filter(
1678
2034
  (v) => typeof v === "number"
1679
2035
  )
1680
2036
  );
1681
2037
  var SERVER_MSG_CODE_NAMES = Object.fromEntries(
1682
- Object.entries(_core.ServerMsgCode).map(([k, v]) => [v, k])
2038
+ Object.entries(ServerMsgCode2).map(([k, v]) => [v, k])
1683
2039
  );
1684
2040
  var BLACK_HOLE = new Logger([
1685
2041
  /* No targets, i.e. black hole logger */
@@ -1734,13 +2090,13 @@ var BrowserSession = class {
1734
2090
  this.publicMeta = ticket.publicMeta;
1735
2091
  __privateSet(this, __socket, socket);
1736
2092
  __privateSet(this, __debug, debug);
1737
- const now = _nullishCoalesce(_optionalChain([createdAt, 'optionalAccess', _49 => _49.getTime, 'call', _50 => _50()]), () => ( Date.now()));
2093
+ const now = _nullishCoalesce(_optionalChain([createdAt, 'optionalAccess', _56 => _56.getTime, 'call', _57 => _57()]), () => ( Date.now()));
1738
2094
  this.createdAt = now;
1739
2095
  __privateSet(this, __lastActiveAt, now);
1740
2096
  __privateSet(this, __hasNotifiedClientStorageUpdateError, false);
1741
2097
  }
1742
2098
  get lastActiveAt() {
1743
- const lastPing = _optionalChain([__privateGet, 'call', _51 => _51(this, __socket), 'access', _52 => _52.getLastPongTimestamp, 'optionalCall', _53 => _53()]);
2099
+ const lastPing = _optionalChain([__privateGet, 'call', _58 => _58(this, __socket), 'access', _59 => _59.getLastPongTimestamp, 'optionalCall', _60 => _60()]);
1744
2100
  if (lastPing && lastPing.getTime() > __privateGet(this, __lastActiveAt)) {
1745
2101
  return lastPing.getTime();
1746
2102
  } else {
@@ -1840,28 +2196,28 @@ var Room = class {
1840
2196
  __publicField(this, "hooks");
1841
2197
  __privateAdd(this, __debug2);
1842
2198
  __privateAdd(this, __allowStreaming);
1843
- const driver = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _54 => _54.storage]), () => ( makeNewInMemoryDriver()));
2199
+ const driver = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _61 => _61.storage]), () => ( makeNewInMemoryDriver()));
1844
2200
  this.meta = meta;
1845
2201
  this.driver = driver;
1846
- this.logger = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _55 => _55.logger]), () => ( BLACK_HOLE));
1847
- __privateSet(this, __allowStreaming, _nullishCoalesce(_optionalChain([options, 'optionalAccess', _56 => _56.allowStreaming]), () => ( true)));
2202
+ this.logger = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _62 => _62.logger]), () => ( BLACK_HOLE));
2203
+ __privateSet(this, __allowStreaming, _nullishCoalesce(_optionalChain([options, 'optionalAccess', _63 => _63.allowStreaming]), () => ( true)));
1848
2204
  this.hooks = {
1849
- isClientMsgAllowed: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _57 => _57.hooks, 'optionalAccess', _58 => _58.isClientMsgAllowed]), () => ( (() => {
2205
+ isClientMsgAllowed: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _64 => _64.hooks, 'optionalAccess', _65 => _65.isClientMsgAllowed]), () => ( (() => {
1850
2206
  return {
1851
2207
  allowed: true
1852
2208
  };
1853
2209
  }))),
1854
2210
  // YYY .load() isn't called on the RoomServer yet! As soon as it does, these hooks will get called
1855
- onRoomWillLoad: _optionalChain([options, 'optionalAccess', _59 => _59.hooks, 'optionalAccess', _60 => _60.onRoomWillLoad]),
1856
- onRoomDidLoad: _optionalChain([options, 'optionalAccess', _61 => _61.hooks, 'optionalAccess', _62 => _62.onRoomDidLoad]),
1857
- onRoomWillUnload: _optionalChain([options, 'optionalAccess', _63 => _63.hooks, 'optionalAccess', _64 => _64.onRoomWillUnload]),
1858
- onRoomDidUnload: _optionalChain([options, 'optionalAccess', _65 => _65.hooks, 'optionalAccess', _66 => _66.onRoomDidUnload]),
1859
- onSessionDidStart: _optionalChain([options, 'optionalAccess', _67 => _67.hooks, 'optionalAccess', _68 => _68.onSessionDidStart]),
1860
- onSessionDidEnd: _optionalChain([options, 'optionalAccess', _69 => _69.hooks, 'optionalAccess', _70 => _70.onSessionDidEnd]),
1861
- postClientMsgStorageDidUpdate: _optionalChain([options, 'optionalAccess', _71 => _71.hooks, 'optionalAccess', _72 => _72.postClientMsgStorageDidUpdate]),
1862
- postClientMsgYdocDidUpdate: _optionalChain([options, 'optionalAccess', _73 => _73.hooks, 'optionalAccess', _74 => _74.postClientMsgYdocDidUpdate])
2211
+ onRoomWillLoad: _optionalChain([options, 'optionalAccess', _66 => _66.hooks, 'optionalAccess', _67 => _67.onRoomWillLoad]),
2212
+ onRoomDidLoad: _optionalChain([options, 'optionalAccess', _68 => _68.hooks, 'optionalAccess', _69 => _69.onRoomDidLoad]),
2213
+ onRoomWillUnload: _optionalChain([options, 'optionalAccess', _70 => _70.hooks, 'optionalAccess', _71 => _71.onRoomWillUnload]),
2214
+ onRoomDidUnload: _optionalChain([options, 'optionalAccess', _72 => _72.hooks, 'optionalAccess', _73 => _73.onRoomDidUnload]),
2215
+ onSessionDidStart: _optionalChain([options, 'optionalAccess', _74 => _74.hooks, 'optionalAccess', _75 => _75.onSessionDidStart]),
2216
+ onSessionDidEnd: _optionalChain([options, 'optionalAccess', _76 => _76.hooks, 'optionalAccess', _77 => _77.onSessionDidEnd]),
2217
+ postClientMsgStorageDidUpdate: _optionalChain([options, 'optionalAccess', _78 => _78.hooks, 'optionalAccess', _79 => _79.postClientMsgStorageDidUpdate]),
2218
+ postClientMsgYdocDidUpdate: _optionalChain([options, 'optionalAccess', _80 => _80.hooks, 'optionalAccess', _81 => _81.postClientMsgYdocDidUpdate])
1863
2219
  };
1864
- __privateSet(this, __debug2, _nullishCoalesce(_optionalChain([options, 'optionalAccess', _75 => _75.enableDebugLogging]), () => ( false)));
2220
+ __privateSet(this, __debug2, _nullishCoalesce(_optionalChain([options, 'optionalAccess', _82 => _82.enableDebugLogging]), () => ( false)));
1865
2221
  }
1866
2222
  get loadingState() {
1867
2223
  if (this._loadData$ === null) {
@@ -1935,13 +2291,13 @@ var Room = class {
1935
2291
  * room will be reloaded from storage.
1936
2292
  */
1937
2293
  unload(ctx) {
1938
- _optionalChain([this, 'access', _76 => _76.hooks, 'access', _77 => _77.onRoomWillUnload, 'optionalCall', _78 => _78(ctx)]);
2294
+ _optionalChain([this, 'access', _83 => _83.hooks, 'access', _84 => _84.onRoomWillUnload, 'optionalCall', _85 => _85(ctx)]);
1939
2295
  if (this._data) {
1940
2296
  this.storage.unload();
1941
2297
  this.yjsStorage.unload();
1942
2298
  }
1943
2299
  this._loadData$ = null;
1944
- _optionalChain([this, 'access', _79 => _79.hooks, 'access', _80 => _80.onRoomDidUnload, 'optionalCall', _81 => _81(ctx)]);
2300
+ _optionalChain([this, 'access', _86 => _86.hooks, 'access', _87 => _87.onRoomDidUnload, 'optionalCall', _88 => _88(ctx)]);
1945
2301
  }
1946
2302
  /**
1947
2303
  * Issues a Ticket with a new/unique actor ID
@@ -1955,17 +2311,17 @@ var Room = class {
1955
2311
  * unused Ticket will simply get garbage collected.
1956
2312
  */
1957
2313
  async createTicket(options) {
1958
- const actor$ = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _82 => _82.actor]), () => ( this.getNextActor()));
2314
+ const actor$ = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _89 => _89.actor]), () => ( this.getNextActor()));
1959
2315
  const sessionKey = _nanoid.nanoid.call(void 0, );
1960
- const info = _optionalChain([options, 'optionalAccess', _83 => _83.info]);
2316
+ const info = _optionalChain([options, 'optionalAccess', _90 => _90.info]);
1961
2317
  const ticket = {
1962
- version: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _84 => _84.version]), () => ( HIGHEST_PROTOCOL_VERSION)),
2318
+ version: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _91 => _91.version]), () => ( HIGHEST_PROTOCOL_VERSION)),
1963
2319
  actor: await actor$,
1964
2320
  sessionKey,
1965
- meta: _optionalChain([options, 'optionalAccess', _85 => _85.meta]),
1966
- publicMeta: _optionalChain([options, 'optionalAccess', _86 => _86.publicMeta]),
1967
- user: _optionalChain([options, 'optionalAccess', _87 => _87.id]) ? { id: options.id, info } : { anonymousId: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _88 => _88.anonymousId]), () => ( _nanoid.nanoid.call(void 0, ))), info },
1968
- scopes: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _89 => _89.scopes]), () => ( ["room:write"]))
2321
+ meta: _optionalChain([options, 'optionalAccess', _92 => _92.meta]),
2322
+ publicMeta: _optionalChain([options, 'optionalAccess', _93 => _93.publicMeta]),
2323
+ user: _optionalChain([options, 'optionalAccess', _94 => _94.id]) ? { id: options.id, info } : { anonymousId: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _95 => _95.anonymousId]), () => ( _nanoid.nanoid.call(void 0, ))), info },
2324
+ scopes: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _96 => _96.scopes]), () => ( ["room:write"]))
1969
2325
  };
1970
2326
  if (__privateGet(this, __debug2)) {
1971
2327
  console.log(`new ticket created: ${JSON.stringify(ticket)}`);
@@ -2050,7 +2406,7 @@ var Room = class {
2050
2406
  );
2051
2407
  for (const leasedSession of leasedSessions) {
2052
2408
  newSession.send({
2053
- type: _core.ServerMsgCode.UPDATE_PRESENCE,
2409
+ type: ServerMsgCode2.UPDATE_PRESENCE,
2054
2410
  actor: leasedSession.actorId,
2055
2411
  targetActor: newSession.actor,
2056
2412
  // full presence to new user
@@ -2090,7 +2446,7 @@ var Room = class {
2090
2446
  this.sendToOthers(
2091
2447
  ticket.sessionKey,
2092
2448
  {
2093
- type: _core.ServerMsgCode.USER_JOINED,
2449
+ type: ServerMsgCode2.USER_JOINED,
2094
2450
  actor: newSession.actor,
2095
2451
  id: newSession.user.id,
2096
2452
  info: newSession.user.info,
@@ -2099,7 +2455,7 @@ var Room = class {
2099
2455
  ctx,
2100
2456
  defer
2101
2457
  );
2102
- const p$ = _optionalChain([this, 'access', _90 => _90.hooks, 'access', _91 => _91.onSessionDidStart, 'optionalCall', _92 => _92(newSession, ctx)]);
2458
+ const p$ = _optionalChain([this, 'access', _97 => _97.hooks, 'access', _98 => _98.onSessionDidStart, 'optionalCall', _99 => _99(newSession, ctx)]);
2103
2459
  if (p$) defer(p$);
2104
2460
  }
2105
2461
  /**
@@ -2121,9 +2477,9 @@ var Room = class {
2121
2477
  const deleted = sessions.delete(key);
2122
2478
  if (deleted) {
2123
2479
  for (const other of this.otherSessions(key)) {
2124
- other.send({ type: _core.ServerMsgCode.USER_LEFT, actor: session.actor });
2480
+ other.send({ type: ServerMsgCode2.USER_LEFT, actor: session.actor });
2125
2481
  }
2126
- const p$ = _optionalChain([this, 'access', _93 => _93.hooks, 'access', _94 => _94.onSessionDidEnd, 'optionalCall', _95 => _95(session, ctx)]);
2482
+ const p$ = _optionalChain([this, 'access', _100 => _100.hooks, 'access', _101 => _101.onSessionDidEnd, 'optionalCall', _102 => _102(session, ctx)]);
2127
2483
  if (p$) defer(p$);
2128
2484
  }
2129
2485
  }
@@ -2154,7 +2510,7 @@ var Room = class {
2154
2510
  );
2155
2511
  }) {
2156
2512
  const text = typeof data === "string" ? data : _core.raise.call(void 0, "Unsupported message format");
2157
- _optionalChain([this, 'access', _96 => _96.sessions, 'access', _97 => _97.get, 'call', _98 => _98(key), 'optionalAccess', _99 => _99.markActive, 'call', _100 => _100()]);
2513
+ _optionalChain([this, 'access', _103 => _103.sessions, 'access', _104 => _104.get, 'call', _105 => _105(key), 'optionalAccess', _106 => _106.markActive, 'call', _107 => _107()]);
2158
2514
  if (text === "ping") {
2159
2515
  await this.handlePing(key, ctx);
2160
2516
  } else {
@@ -2267,7 +2623,7 @@ var Room = class {
2267
2623
  await this.driver.put_leased_session(session);
2268
2624
  this.sendToAll(
2269
2625
  {
2270
- type: _core.ServerMsgCode.USER_JOINED,
2626
+ type: ServerMsgCode2.USER_JOINED,
2271
2627
  actor: actorId,
2272
2628
  id: sessionId,
2273
2629
  info,
@@ -2278,7 +2634,7 @@ var Room = class {
2278
2634
  );
2279
2635
  this.sendToAll(
2280
2636
  {
2281
- type: _core.ServerMsgCode.UPDATE_PRESENCE,
2637
+ type: ServerMsgCode2.UPDATE_PRESENCE,
2282
2638
  actor: actorId,
2283
2639
  data: presence,
2284
2640
  targetActor: 1
@@ -2301,7 +2657,7 @@ var Room = class {
2301
2657
  await this.driver.put_leased_session(updatedSession);
2302
2658
  this.sendToAll(
2303
2659
  {
2304
- type: _core.ServerMsgCode.UPDATE_PRESENCE,
2660
+ type: ServerMsgCode2.UPDATE_PRESENCE,
2305
2661
  actor: existingSession.actorId,
2306
2662
  data: presence
2307
2663
  // Send only the patch, not the full merged presence
@@ -2346,7 +2702,7 @@ var Room = class {
2346
2702
  }) {
2347
2703
  this.sendToAll(
2348
2704
  {
2349
- type: _core.ServerMsgCode.USER_LEFT,
2705
+ type: ServerMsgCode2.USER_LEFT,
2350
2706
  actor: session.actorId
2351
2707
  },
2352
2708
  ctx,
@@ -2368,6 +2724,87 @@ var Room = class {
2368
2724
  await this.deleteLeasedSession(session, ctx, defer);
2369
2725
  }
2370
2726
  }
2727
+ // ---------------------------------------------------------------------------
2728
+ // Feed APIs
2729
+ // ---------------------------------------------------------------------------
2730
+ /**
2731
+ * List feeds with pagination and filtering.
2732
+ */
2733
+ async listFeeds(options) {
2734
+ return await this.driver.list_feeds(options);
2735
+ }
2736
+ /**
2737
+ * Get a specific feed by feed ID.
2738
+ */
2739
+ async getFeed(feedId) {
2740
+ return await this.driver.get_feed(feedId);
2741
+ }
2742
+ /**
2743
+ * Create a new feed.
2744
+ * If timestamp is not provided, current server time is used.
2745
+ */
2746
+ async createFeed(feed) {
2747
+ const now = _nullishCoalesce(feed.timestamp, () => ( Date.now()));
2748
+ const fullFeed = {
2749
+ ...feed,
2750
+ createdAt: now,
2751
+ updatedAt: now
2752
+ };
2753
+ await this.driver.create_feed(fullFeed);
2754
+ return fullFeed;
2755
+ }
2756
+ /**
2757
+ * Update a feed's metadata.
2758
+ */
2759
+ async updateFeedMetadata(feedId, metadata) {
2760
+ await this.driver.update_feed_metadata(feedId, metadata);
2761
+ }
2762
+ /**
2763
+ * Delete a feed.
2764
+ */
2765
+ async deleteFeed(feedId) {
2766
+ await this.driver.delete_feed(feedId);
2767
+ }
2768
+ /**
2769
+ * List feed messages for a feed with pagination.
2770
+ */
2771
+ async listFeedMessages(feedId, options) {
2772
+ return await this.driver.list_feed_messages(feedId, options);
2773
+ }
2774
+ /**
2775
+ * Add a message to a feed.
2776
+ * If message id is not provided, a unique ID is automatically generated.
2777
+ * If timestamp is not provided, current server time is used.
2778
+ */
2779
+ async addFeedMessage(feedId, message) {
2780
+ const now = _nullishCoalesce(message.timestamp, () => ( Date.now()));
2781
+ const fullMessage = {
2782
+ id: _nullishCoalesce(message.id, () => ( _nanoid.nanoid.call(void 0, ))),
2783
+ createdAt: now,
2784
+ updatedAt: now,
2785
+ data: message.data
2786
+ };
2787
+ await this.driver.add_feed_message(feedId, fullMessage);
2788
+ return fullMessage;
2789
+ }
2790
+ /**
2791
+ * Update a feed message's data.
2792
+ * Returns the updated message.
2793
+ */
2794
+ async updateFeedMessage(feedId, messageId, data, timestamp) {
2795
+ return await this.driver.update_feed_message(
2796
+ feedId,
2797
+ messageId,
2798
+ data,
2799
+ _nullishCoalesce(timestamp, () => ( Date.now()))
2800
+ );
2801
+ }
2802
+ /**
2803
+ * Delete a feed message.
2804
+ */
2805
+ async deleteFeedMessage(feedId, messageId) {
2806
+ await this.driver.delete_feed_message(feedId, messageId);
2807
+ }
2371
2808
  /**
2372
2809
  * Will send the given ServerMsg through all Session, except the Session
2373
2810
  * where the message originates from.
@@ -2428,7 +2865,7 @@ var Room = class {
2428
2865
  }
2429
2866
  // Don't ever manually call this!
2430
2867
  async _load(ctx) {
2431
- await _optionalChain([this, 'access', _101 => _101.hooks, 'access', _102 => _102.onRoomWillLoad, 'optionalCall', _103 => _103(ctx)]);
2868
+ await _optionalChain([this, 'access', _108 => _108.hooks, 'access', _109 => _109.onRoomWillLoad, 'optionalCall', _110 => _110(ctx)]);
2432
2869
  const storage = await this._loadStorage();
2433
2870
  const yjsStorage = await this._loadYjsStorage();
2434
2871
  this._data = {
@@ -2436,7 +2873,7 @@ var Room = class {
2436
2873
  storage,
2437
2874
  yjsStorage
2438
2875
  };
2439
- await _optionalChain([this, 'access', _104 => _104.hooks, 'access', _105 => _105.onRoomDidLoad, 'optionalCall', _106 => _106(ctx)]);
2876
+ await _optionalChain([this, 'access', _111 => _111.hooks, 'access', _112 => _112.onRoomDidLoad, 'optionalCall', _113 => _113(ctx)]);
2440
2877
  }
2441
2878
  /**
2442
2879
  * Returns a new, unique, actor ID.
@@ -2477,7 +2914,7 @@ var Room = class {
2477
2914
  }
2478
2915
  const sent = session.sendPong();
2479
2916
  if (sent !== 0) {
2480
- await _optionalChain([this, 'access', _107 => _107.hooks, 'access', _108 => _108.onDidPong, 'optionalCall', _109 => _109(ctx)]);
2917
+ await _optionalChain([this, 'access', _114 => _114.hooks, 'access', _115 => _115.onDidPong, 'optionalCall', _116 => _116(ctx)]);
2481
2918
  }
2482
2919
  }
2483
2920
  async _processClientMsg_withExclusiveAccess(sessionKey, messages, ctx, defer) {
@@ -2506,7 +2943,7 @@ var Room = class {
2506
2943
  } else {
2507
2944
  if (!session.hasNotifiedClientStorageUpdateError) {
2508
2945
  toReply.push({
2509
- type: _core.ServerMsgCode.REJECT_STORAGE_OP,
2946
+ type: ServerMsgCode2.REJECT_STORAGE_OP,
2510
2947
  opIds: msg.type === _core.ClientMsgCode.UPDATE_STORAGE ? msg.ops.map((op2) => op2.opId) : [],
2511
2948
  reason: isMsgAllowed.reason
2512
2949
  });
@@ -2570,7 +3007,7 @@ var Room = class {
2570
3007
  switch (msg.type) {
2571
3008
  case _core.ClientMsgCode.UPDATE_PRESENCE: {
2572
3009
  scheduleFanOut({
2573
- type: _core.ServerMsgCode.UPDATE_PRESENCE,
3010
+ type: ServerMsgCode2.UPDATE_PRESENCE,
2574
3011
  actor: session.actor,
2575
3012
  data: msg.data,
2576
3013
  targetActor: msg.targetActor
@@ -2579,7 +3016,7 @@ var Room = class {
2579
3016
  }
2580
3017
  case _core.ClientMsgCode.BROADCAST_EVENT: {
2581
3018
  scheduleFanOut({
2582
- type: _core.ServerMsgCode.BROADCASTED_EVENT,
3019
+ type: ServerMsgCode2.BROADCASTED_EVENT,
2583
3020
  actor: session.actor,
2584
3021
  event: msg.event
2585
3022
  });
@@ -2594,29 +3031,29 @@ var Room = class {
2594
3031
  NODES_PER_CHUNK
2595
3032
  )) {
2596
3033
  replyImmediately({
2597
- type: _core.ServerMsgCode.STORAGE_CHUNK,
3034
+ type: ServerMsgCode2.STORAGE_CHUNK,
2598
3035
  nodes: chunk
2599
3036
  });
2600
3037
  }
2601
3038
  } else {
2602
3039
  replyImmediately({
2603
- type: _core.ServerMsgCode.STORAGE_CHUNK,
3040
+ type: ServerMsgCode2.STORAGE_CHUNK,
2604
3041
  nodes: Array.from(
2605
3042
  _core.nodeStreamToCompactNodes.call(void 0, this.storage.loadedDriver.iter_nodes())
2606
3043
  )
2607
3044
  });
2608
3045
  }
2609
- replyImmediately({ type: _core.ServerMsgCode.STORAGE_STREAM_END });
3046
+ replyImmediately({ type: ServerMsgCode2.STORAGE_STREAM_END });
2610
3047
  } else {
2611
3048
  replyImmediately({
2612
- type: _core.ServerMsgCode.STORAGE_STATE_V7,
3049
+ type: ServerMsgCode2.STORAGE_STATE_V7,
2613
3050
  items: Array.from(this.storage.loadedDriver.iter_nodes())
2614
3051
  });
2615
3052
  }
2616
3053
  break;
2617
3054
  }
2618
3055
  case _core.ClientMsgCode.UPDATE_STORAGE: {
2619
- _optionalChain([this, 'access', _110 => _110.driver, 'access', _111 => _111.bump_storage_version, 'optionalCall', _112 => _112()]);
3056
+ _optionalChain([this, 'access', _117 => _117.driver, 'access', _118 => _118.bump_storage_version, 'optionalCall', _119 => _119()]);
2620
3057
  const result = await this.storage.applyOps(msg.ops);
2621
3058
  const opsToForward = result.flatMap(
2622
3059
  (r) => r.action === "accepted" ? [r.op] : []
@@ -2633,22 +3070,22 @@ var Room = class {
2633
3070
  });
2634
3071
  if (opsToForward.length > 0) {
2635
3072
  scheduleFanOut({
2636
- type: _core.ServerMsgCode.UPDATE_STORAGE,
3073
+ type: ServerMsgCode2.UPDATE_STORAGE,
2637
3074
  ops: opsToForward.map(stripOpId)
2638
3075
  });
2639
3076
  scheduleReply({
2640
- type: _core.ServerMsgCode.UPDATE_STORAGE,
3077
+ type: ServerMsgCode2.UPDATE_STORAGE,
2641
3078
  ops: opsToForward
2642
3079
  });
2643
3080
  }
2644
3081
  if (opsToSendBack.length > 0) {
2645
3082
  replyImmediately({
2646
- type: _core.ServerMsgCode.UPDATE_STORAGE,
3083
+ type: ServerMsgCode2.UPDATE_STORAGE,
2647
3084
  ops: opsToSendBack
2648
3085
  });
2649
3086
  }
2650
3087
  if (opsToForward.length > 0) {
2651
- const p$ = _optionalChain([this, 'access', _113 => _113.hooks, 'access', _114 => _114.postClientMsgStorageDidUpdate, 'optionalCall', _115 => _115(ctx)]);
3088
+ const p$ = _optionalChain([this, 'access', _120 => _120.hooks, 'access', _121 => _121.postClientMsgStorageDidUpdate, 'optionalCall', _122 => _122(ctx)]);
2652
3089
  if (p$) defer(p$);
2653
3090
  }
2654
3091
  break;
@@ -2664,7 +3101,7 @@ var Room = class {
2664
3101
  ]);
2665
3102
  if (update !== null && snapshotHash !== null) {
2666
3103
  replyImmediately({
2667
- type: _core.ServerMsgCode.UPDATE_YDOC,
3104
+ type: ServerMsgCode2.UPDATE_YDOC,
2668
3105
  update,
2669
3106
  isSync: true,
2670
3107
  // this is no longer used by the client, instead we use the presence of stateVector
@@ -2687,7 +3124,7 @@ var Room = class {
2687
3124
  break;
2688
3125
  this.sendToAll(
2689
3126
  {
2690
- type: _core.ServerMsgCode.UPDATE_YDOC,
3127
+ type: ServerMsgCode2.UPDATE_YDOC,
2691
3128
  update,
2692
3129
  guid,
2693
3130
  isSync: false,
@@ -2699,15 +3136,185 @@ var Room = class {
2699
3136
  defer
2700
3137
  );
2701
3138
  if (result.isUpdated) {
2702
- const p$ = _optionalChain([this, 'access', _116 => _116.hooks, 'access', _117 => _117.postClientMsgYdocDidUpdate, 'optionalCall', _118 => _118(ctx, session)]);
3139
+ const p$ = _optionalChain([this, 'access', _123 => _123.hooks, 'access', _124 => _124.postClientMsgYdocDidUpdate, 'optionalCall', _125 => _125(ctx, session)]);
2703
3140
  if (p$) defer(p$);
2704
3141
  }
2705
3142
  break;
2706
3143
  }
3144
+ case FeedMsgCode.FETCH_FEEDS: {
3145
+ const fetchMsg = msg;
3146
+ const [result, err] = await tryCatch(
3147
+ this.listFeeds({
3148
+ cursor: fetchMsg.cursor,
3149
+ since: fetchMsg.since,
3150
+ limit: fetchMsg.limit,
3151
+ metadata: fetchMsg.metadata
3152
+ })
3153
+ );
3154
+ if (err) {
3155
+ replyImmediately(feedFailureServerMsg(fetchMsg.requestId, err));
3156
+ break;
3157
+ }
3158
+ replyImmediately({
3159
+ type: FeedMsgCode.FEEDS_LIST,
3160
+ requestId: fetchMsg.requestId,
3161
+ feeds: result.feeds,
3162
+ nextCursor: result.nextCursor
3163
+ });
3164
+ break;
3165
+ }
3166
+ case FeedMsgCode.FETCH_FEED_MESSAGES: {
3167
+ const fetchMsg = msg;
3168
+ const [result, err] = await tryCatch(
3169
+ this.listFeedMessages(fetchMsg.feedId, {
3170
+ cursor: fetchMsg.cursor,
3171
+ since: fetchMsg.since,
3172
+ limit: fetchMsg.limit
3173
+ })
3174
+ );
3175
+ if (err) {
3176
+ replyImmediately(feedFailureServerMsg(fetchMsg.requestId, err));
3177
+ break;
3178
+ }
3179
+ replyImmediately({
3180
+ type: FeedMsgCode.FEED_MESSAGES_LIST,
3181
+ requestId: fetchMsg.requestId,
3182
+ feedId: fetchMsg.feedId,
3183
+ messages: result.messages,
3184
+ nextCursor: result.nextCursor
3185
+ });
3186
+ break;
3187
+ }
3188
+ case FeedMsgCode.ADD_FEED: {
3189
+ const addMsg = msg;
3190
+ const [feed, err] = await tryCatch(
3191
+ this.createFeed({
3192
+ feedId: addMsg.feedId,
3193
+ metadata: _nullishCoalesce(addMsg.metadata, () => ( {})),
3194
+ timestamp: addMsg.timestamp
3195
+ })
3196
+ );
3197
+ if (err) {
3198
+ replyImmediately(feedFailureServerMsg(addMsg.requestId, err));
3199
+ break;
3200
+ }
3201
+ const feedsMsg = {
3202
+ type: FeedMsgCode.FEEDS_ADDED,
3203
+ feeds: [feed]
3204
+ };
3205
+ replyImmediately(feedsMsg);
3206
+ scheduleFanOut(feedsMsg);
3207
+ break;
3208
+ }
3209
+ case FeedMsgCode.UPDATE_FEED: {
3210
+ const updateMsg = msg;
3211
+ const [, metaErr] = await tryCatch(
3212
+ this.updateFeedMetadata(updateMsg.feedId, updateMsg.metadata)
3213
+ );
3214
+ if (metaErr) {
3215
+ replyImmediately(feedFailureServerMsg(updateMsg.requestId, metaErr));
3216
+ break;
3217
+ }
3218
+ const feed = await this.getFeed(updateMsg.feedId);
3219
+ if (!feed) {
3220
+ replyImmediately(
3221
+ feedRequestFailed(
3222
+ updateMsg.requestId,
3223
+ FeedRequestErrorCode.FEED_NOT_FOUND
3224
+ )
3225
+ );
3226
+ break;
3227
+ }
3228
+ const feedsMsg = {
3229
+ type: FeedMsgCode.FEEDS_UPDATED,
3230
+ feeds: [feed]
3231
+ };
3232
+ replyImmediately(feedsMsg);
3233
+ scheduleFanOut(feedsMsg);
3234
+ break;
3235
+ }
3236
+ case FeedMsgCode.DELETE_FEED: {
3237
+ const deleteMsg = msg;
3238
+ const [, err] = await tryCatch(this.deleteFeed(deleteMsg.feedId));
3239
+ if (err) {
3240
+ replyImmediately(feedFailureServerMsg(deleteMsg.requestId, err));
3241
+ break;
3242
+ }
3243
+ const feedDeletedMsg = {
3244
+ type: FeedMsgCode.FEED_DELETED,
3245
+ feedId: deleteMsg.feedId
3246
+ };
3247
+ replyImmediately(feedDeletedMsg);
3248
+ scheduleFanOut(feedDeletedMsg);
3249
+ break;
3250
+ }
3251
+ case FeedMsgCode.ADD_FEED_MESSAGE: {
3252
+ const addMsg = msg;
3253
+ const [message, err] = await tryCatch(
3254
+ this.addFeedMessage(addMsg.feedId, {
3255
+ data: addMsg.data,
3256
+ id: addMsg.id,
3257
+ timestamp: addMsg.timestamp
3258
+ })
3259
+ );
3260
+ if (err) {
3261
+ replyImmediately(feedFailureServerMsg(addMsg.requestId, err));
3262
+ break;
3263
+ }
3264
+ const feedMessagesMsg = {
3265
+ type: FeedMsgCode.FEED_MESSAGES_ADDED,
3266
+ feedId: addMsg.feedId,
3267
+ messages: [message]
3268
+ };
3269
+ replyImmediately(feedMessagesMsg);
3270
+ scheduleFanOut(feedMessagesMsg);
3271
+ break;
3272
+ }
3273
+ case FeedMsgCode.UPDATE_FEED_MESSAGE: {
3274
+ const updateMsg = msg;
3275
+ const [message, err] = await tryCatch(
3276
+ this.updateFeedMessage(
3277
+ updateMsg.feedId,
3278
+ updateMsg.messageId,
3279
+ updateMsg.data,
3280
+ updateMsg.timestamp
3281
+ )
3282
+ );
3283
+ if (err) {
3284
+ replyImmediately(feedFailureServerMsg(updateMsg.requestId, err));
3285
+ break;
3286
+ }
3287
+ const feedMessagesMsg = {
3288
+ type: FeedMsgCode.FEED_MESSAGES_UPDATED,
3289
+ feedId: updateMsg.feedId,
3290
+ messages: [message]
3291
+ };
3292
+ replyImmediately(feedMessagesMsg);
3293
+ scheduleFanOut(feedMessagesMsg);
3294
+ break;
3295
+ }
3296
+ case FeedMsgCode.DELETE_FEED_MESSAGE: {
3297
+ const deleteMsg = msg;
3298
+ const [, err] = await tryCatch(
3299
+ this.deleteFeedMessage(deleteMsg.feedId, deleteMsg.messageId)
3300
+ );
3301
+ if (err) {
3302
+ replyImmediately(feedFailureServerMsg(deleteMsg.requestId, err));
3303
+ break;
3304
+ }
3305
+ const feedMessagesMsg = {
3306
+ type: FeedMsgCode.FEED_MESSAGES_DELETED,
3307
+ feedId: deleteMsg.feedId,
3308
+ messageIds: [deleteMsg.messageId]
3309
+ };
3310
+ replyImmediately(feedMessagesMsg);
3311
+ scheduleFanOut(feedMessagesMsg);
3312
+ break;
3313
+ }
2707
3314
  default: {
2708
3315
  try {
2709
3316
  return _core.assertNever.call(void 0, msg, "Unrecognized client msg");
2710
- } catch (e3) {
3317
+ } catch (e5) {
2711
3318
  }
2712
3319
  }
2713
3320
  }
@@ -2751,5 +3358,14 @@ __allowStreaming = new WeakMap();
2751
3358
 
2752
3359
 
2753
3360
 
2754
- exports.BackendSession = BackendSession; exports.BrowserSession = BrowserSession; exports.ConsoleTarget = ConsoleTarget; exports.DefaultMap = DefaultMap; exports.InMemoryDriver = InMemoryDriver; exports.LogLevel = LogLevel; exports.LogTarget = LogTarget; exports.Logger = Logger; exports.NestedMap = NestedMap; exports.ProtocolVersion = ProtocolVersion; exports.ROOT_YDOC_ID = ROOT_YDOC_ID; exports.Room = Room; exports.UniqueMap = UniqueMap; exports.ackIgnoredOp = ackIgnoredOp; exports.clientMsgDecoder = clientMsgDecoder; exports.concatUint8Arrays = concatUint8Arrays; exports.guidDecoder = guidDecoder; exports.isLeasedSessionExpired = isLeasedSessionExpired; exports.jsonObjectYolo = jsonObjectYolo; exports.jsonYolo = jsonYolo; exports.makeInMemorySnapshot = makeInMemorySnapshot; exports.makeMetadataDB = makeMetadataDB; exports.plainLsonToNodeStream = plainLsonToNodeStream; exports.protocolVersionDecoder = protocolVersionDecoder; exports.quote = quote; exports.serializeServerMsg = serialize; exports.snapshotToLossyJson_eager = snapshotToLossyJson_eager; exports.snapshotToLossyJson_lazy = snapshotToLossyJson_lazy; exports.snapshotToNodeStream = snapshotToNodeStream; exports.snapshotToPlainLson_eager = snapshotToPlainLson_eager; exports.snapshotToPlainLson_lazy = snapshotToPlainLson_lazy; exports.test_only__Storage = Storage; exports.test_only__YjsStorage = YjsStorage; exports.transientClientMsgDecoder = transientClientMsgDecoder; exports.tryCatch = tryCatch;
3361
+
3362
+
3363
+
3364
+
3365
+
3366
+
3367
+
3368
+
3369
+
3370
+ exports.BackendSession = BackendSession; exports.BrowserSession = BrowserSession; exports.ConsoleTarget = ConsoleTarget; exports.DefaultMap = DefaultMap; exports.FeedMsgCode = FeedMsgCode; exports.FeedRequestErrorCode = FeedRequestErrorCode; exports.InMemoryDriver = InMemoryDriver; exports.LogLevel = LogLevel; exports.LogTarget = LogTarget; exports.Logger = Logger; exports.NestedMap = NestedMap; exports.ProtocolVersion = ProtocolVersion; exports.ROOT_YDOC_ID = ROOT_YDOC_ID; exports.Room = Room; exports.UniqueMap = UniqueMap; exports.ackIgnoredOp = ackIgnoredOp; exports.clientMsgDecoder = clientMsgDecoder; exports.concatUint8Arrays = concatUint8Arrays; exports.feedFailureServerMsg = feedFailureServerMsg; exports.feedMetadataIdDecoder = feedMetadataIdDecoder; exports.feedMetadataUpdateDecoder = feedMetadataUpdateDecoder; exports.feedRequestFailed = feedRequestFailed; exports.fetchFeedsMetadataFilterDecoder = fetchFeedsMetadataFilterDecoder; exports.guidDecoder = guidDecoder; exports.isLeasedSessionExpired = isLeasedSessionExpired; exports.jsonObjectYolo = jsonObjectYolo; exports.jsonYolo = jsonYolo; exports.makeInMemorySnapshot = makeInMemorySnapshot; exports.makeMetadataDB = makeMetadataDB; exports.mapFeedError = mapFeedError; exports.optionalFeedMetadataDecoder = optionalFeedMetadataDecoder; exports.plainLsonToNodeStream = plainLsonToNodeStream; exports.protocolVersionDecoder = protocolVersionDecoder; exports.quote = quote; exports.serializeServerMsg = serialize; exports.snapshotToLossyJson_eager = snapshotToLossyJson_eager; exports.snapshotToLossyJson_lazy = snapshotToLossyJson_lazy; exports.snapshotToNodeStream = snapshotToNodeStream; exports.snapshotToPlainLson_eager = snapshotToPlainLson_eager; exports.snapshotToPlainLson_lazy = snapshotToPlainLson_lazy; exports.test_only__Storage = Storage; exports.test_only__YjsStorage = YjsStorage; exports.transientClientMsgDecoder = transientClientMsgDecoder; exports.tryCatch = tryCatch;
2755
3371
  //# sourceMappingURL=index.cjs.map