@super-line/server 0.7.0 → 0.8.0

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
@@ -16276,7 +16276,6 @@ __export(index_exports, {
16276
16276
  resolvePrincipal: () => resolvePrincipal
16277
16277
  });
16278
16278
  module.exports = __toCommonJS(index_exports);
16279
- var import_node_crypto = require("crypto");
16280
16279
  var import_core2 = require("@super-line/core");
16281
16280
 
16282
16281
  // src/conn.ts
@@ -16448,12 +16447,17 @@ function createInMemoryAdapter(bus = new MemoryBus()) {
16448
16447
  }
16449
16448
 
16450
16449
  // src/index.ts
16450
+ var randomUUID = () => globalThis.crypto.randomUUID();
16451
16451
  var ROOM = "r:";
16452
16452
  var TOPIC = "t:";
16453
16453
  var CONN = "c:";
16454
16454
  var USER = "u:";
16455
16455
  var REPLY = "reply:";
16456
16456
  var INSPECT = "i:";
16457
+ var inspectorEncoder = new TextEncoder();
16458
+ function encodedByteSize(encoded) {
16459
+ return typeof encoded === "string" ? inspectorEncoder.encode(encoded).length : encoded.byteLength;
16460
+ }
16457
16461
  var STORE = "s:";
16458
16462
  var SERVER_ORIGIN = "server";
16459
16463
  function createSuperLineServer(contract, opts) {
@@ -16469,8 +16473,9 @@ function createSuperLineServer(contract, opts) {
16469
16473
  const inspectorConns = /* @__PURE__ */ new Set();
16470
16474
  const members = /* @__PURE__ */ new Map();
16471
16475
  const busListeners = /* @__PURE__ */ new Map();
16472
- const instanceId = (0, import_node_crypto.randomUUID)();
16473
- const nodeName = opts.nodeName ?? process.env.SUPER_LINE_NODE_NAME ?? instanceId.slice(0, 8);
16476
+ const instanceId = randomUUID();
16477
+ const envNodeName = typeof process !== "undefined" ? process.env.SUPER_LINE_NODE_NAME : void 0;
16478
+ const nodeName = opts.nodeName ?? envNodeName ?? instanceId.slice(0, 8);
16474
16479
  const replyChannel = REPLY + instanceId;
16475
16480
  let impl = {};
16476
16481
  let closing = false;
@@ -16572,12 +16577,13 @@ function createSuperLineServer(contract, opts) {
16572
16577
  }
16573
16578
  if (inspectorEnabled)
16574
16579
  emitInspectorEvent(
16575
- env.ok ? { type: "msg.serverReply", target: conn.id, name: r.name, ok: true, output: safeSnapshot(env.d) } : {
16580
+ env.ok ? { type: "msg.serverReply", target: conn.id, name: r.name, ok: true, output: safeSnapshot(env.d), reqId: r.corrId } : {
16576
16581
  type: "msg.serverReply",
16577
16582
  target: conn.id,
16578
16583
  name: r.name,
16579
16584
  ok: false,
16580
- error: { code: env.code, message: env.m }
16585
+ error: { code: env.code, message: env.m },
16586
+ reqId: r.corrId
16581
16587
  }
16582
16588
  );
16583
16589
  void adapter.publish(REPLY + r.origin, serializer.encode(env));
@@ -16602,7 +16608,14 @@ function createSuperLineServer(contract, opts) {
16602
16608
  }
16603
16609
  function emitInspectorEvent(event) {
16604
16610
  if (!inspectorEnabled) return;
16605
- void adapter.publish(INSPECT + "events", serializer.encode({ t: "pub", c: "events", d: event }));
16611
+ const payload = (0, import_core2.eventPayload)(event);
16612
+ const envelope = {
16613
+ event,
16614
+ ts: Date.now(),
16615
+ originNodeId: instanceId,
16616
+ byteSize: payload === void 0 ? void 0 : encodedByteSize(serializer.encode(payload))
16617
+ };
16618
+ void adapter.publish(INSPECT + "events", serializer.encode({ t: "pub", c: "events", d: envelope }));
16606
16619
  }
16607
16620
  function joinChannel(conn, channel) {
16608
16621
  conn.channels.add(channel);
@@ -16795,7 +16808,7 @@ function createSuperLineServer(contract, opts) {
16795
16808
  raw.close();
16796
16809
  return;
16797
16810
  }
16798
- const connId = (0, import_node_crypto.randomUUID)();
16811
+ const connId = randomUUID();
16799
16812
  const conn = new Conn(
16800
16813
  raw,
16801
16814
  connId,
@@ -16900,7 +16913,8 @@ function createSuperLineServer(contract, opts) {
16900
16913
  connId: conn.id,
16901
16914
  name: info.name,
16902
16915
  ok: false,
16903
- error: { code: e.code, message: e.message }
16916
+ error: { code: e.code, message: e.message },
16917
+ reqId: id
16904
16918
  });
16905
16919
  }
16906
16920
  }
@@ -16919,7 +16933,8 @@ function createSuperLineServer(contract, opts) {
16919
16933
  connId: conn.id,
16920
16934
  role: conn.role,
16921
16935
  name: frame.m,
16922
- input: safeSnapshot(input)
16936
+ input: safeSnapshot(input),
16937
+ reqId: frame.i
16923
16938
  });
16924
16939
  const output = await handler(input, conn.ctx, conn);
16925
16940
  if (inspectorEnabled)
@@ -16928,7 +16943,8 @@ function createSuperLineServer(contract, opts) {
16928
16943
  connId: conn.id,
16929
16944
  name: frame.m,
16930
16945
  ok: true,
16931
- output: safeSnapshot(output)
16946
+ output: safeSnapshot(output),
16947
+ reqId: frame.i
16932
16948
  });
16933
16949
  conn.send({ t: "res", i: frame.i, d: output });
16934
16950
  });
@@ -17007,20 +17023,29 @@ function createSuperLineServer(contract, opts) {
17007
17023
  if (inspectorEnabled) emitInspectorEvent({ type: "store.unsubscribe", connId: conn.id, store: frame.n, id: frame.id });
17008
17024
  }
17009
17025
  for (const [name, store] of Object.entries(storeMap)) {
17026
+ const isSelf = store.clustering === "self";
17010
17027
  store.onChange((change) => {
17028
+ const channel = STORE + name + ":" + change.id;
17029
+ if (isSelf) {
17030
+ const set = members.get(channel);
17031
+ if (!set) return;
17032
+ const payload = serializer.encode({ t: "sch", n: name, id: change.id, u: change.update, o: change.origin });
17033
+ for (const conn of set) conn.sendRaw(payload);
17034
+ return;
17035
+ }
17011
17036
  if (relaying) return;
17012
17037
  void adapter.publish(
17013
- STORE + name + ":" + change.id,
17014
- serializer.encode({
17015
- t: "sch",
17016
- n: name,
17017
- id: change.id,
17018
- u: change.update,
17019
- o: change.origin,
17020
- nd: instanceId
17021
- })
17038
+ channel,
17039
+ serializer.encode({ t: "sch", n: name, id: change.id, u: change.update, o: change.origin, nd: instanceId })
17022
17040
  );
17023
17041
  });
17042
+ if (isSelf)
17043
+ store.onDelete?.((id) => {
17044
+ const set = members.get(STORE + name + ":" + id);
17045
+ if (!set) return;
17046
+ const payload = serializer.encode({ t: "sdel", n: name, id });
17047
+ for (const conn of set) conn.sendRaw(payload);
17048
+ });
17024
17049
  }
17025
17050
  function handleStoreRelay(channel, payload) {
17026
17051
  const set = members.get(channel);
@@ -17034,6 +17059,10 @@ function createSuperLineServer(contract, opts) {
17034
17059
  if (frame.nd === instanceId) return;
17035
17060
  const store = storeMap[frame.n];
17036
17061
  if (!store || store.clustering !== "relay") return;
17062
+ if (frame.t === "sdel") {
17063
+ void store.delete(frame.id);
17064
+ return;
17065
+ }
17037
17066
  relaying = true;
17038
17067
  try {
17039
17068
  void store.apply({ id: frame.id, update: frame.u, origin: frame.o });
@@ -17141,7 +17170,7 @@ function createSuperLineServer(contract, opts) {
17141
17170
  { once: true }
17142
17171
  );
17143
17172
  if (inspectorEnabled)
17144
- emitInspectorEvent({ type: "msg.serverRequest", target: id, name, input: safeSnapshot(input) });
17173
+ emitInspectorEvent({ type: "msg.serverRequest", target: id, name, input: safeSnapshot(input), reqId });
17145
17174
  const env = { p: "req", o: instanceId, i: reqId, m: name, d: input };
17146
17175
  void adapter.publish(CONN + id, serializer.encode(env));
17147
17176
  });
@@ -17180,6 +17209,11 @@ function createSuperLineServer(contract, opts) {
17180
17209
  },
17181
17210
  async delete(id) {
17182
17211
  await store.delete(id);
17212
+ if (store.clustering !== "self")
17213
+ void adapter.publish(
17214
+ STORE + name + ":" + id,
17215
+ serializer.encode({ t: "sdel", n: name, id, nd: instanceId })
17216
+ );
17183
17217
  if (inspectorEnabled) emitInspectorEvent({ type: "store.delete", store: name, id });
17184
17218
  },
17185
17219
  list() {
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import "./chunk-MLKGABMK.js";
2
2
 
3
3
  // src/index.ts
4
- import { randomUUID } from "crypto";
5
4
  import {
6
5
  jsonSerializer,
7
6
  validate,
8
7
  SuperLineError,
9
8
  INSPECTOR_ROLE,
10
- classifyContract
9
+ classifyContract,
10
+ eventPayload
11
11
  } from "@super-line/core";
12
12
 
13
13
  // src/conn.ts
@@ -179,12 +179,17 @@ function createInMemoryAdapter(bus = new MemoryBus()) {
179
179
  }
180
180
 
181
181
  // src/index.ts
182
+ var randomUUID = () => globalThis.crypto.randomUUID();
182
183
  var ROOM = "r:";
183
184
  var TOPIC = "t:";
184
185
  var CONN = "c:";
185
186
  var USER = "u:";
186
187
  var REPLY = "reply:";
187
188
  var INSPECT = "i:";
189
+ var inspectorEncoder = new TextEncoder();
190
+ function encodedByteSize(encoded) {
191
+ return typeof encoded === "string" ? inspectorEncoder.encode(encoded).length : encoded.byteLength;
192
+ }
188
193
  var STORE = "s:";
189
194
  var SERVER_ORIGIN = "server";
190
195
  function createSuperLineServer(contract, opts) {
@@ -201,7 +206,8 @@ function createSuperLineServer(contract, opts) {
201
206
  const members = /* @__PURE__ */ new Map();
202
207
  const busListeners = /* @__PURE__ */ new Map();
203
208
  const instanceId = randomUUID();
204
- const nodeName = opts.nodeName ?? process.env.SUPER_LINE_NODE_NAME ?? instanceId.slice(0, 8);
209
+ const envNodeName = typeof process !== "undefined" ? process.env.SUPER_LINE_NODE_NAME : void 0;
210
+ const nodeName = opts.nodeName ?? envNodeName ?? instanceId.slice(0, 8);
205
211
  const replyChannel = REPLY + instanceId;
206
212
  let impl = {};
207
213
  let closing = false;
@@ -303,12 +309,13 @@ function createSuperLineServer(contract, opts) {
303
309
  }
304
310
  if (inspectorEnabled)
305
311
  emitInspectorEvent(
306
- env.ok ? { type: "msg.serverReply", target: conn.id, name: r.name, ok: true, output: safeSnapshot(env.d) } : {
312
+ env.ok ? { type: "msg.serverReply", target: conn.id, name: r.name, ok: true, output: safeSnapshot(env.d), reqId: r.corrId } : {
307
313
  type: "msg.serverReply",
308
314
  target: conn.id,
309
315
  name: r.name,
310
316
  ok: false,
311
- error: { code: env.code, message: env.m }
317
+ error: { code: env.code, message: env.m },
318
+ reqId: r.corrId
312
319
  }
313
320
  );
314
321
  void adapter.publish(REPLY + r.origin, serializer.encode(env));
@@ -333,7 +340,14 @@ function createSuperLineServer(contract, opts) {
333
340
  }
334
341
  function emitInspectorEvent(event) {
335
342
  if (!inspectorEnabled) return;
336
- void adapter.publish(INSPECT + "events", serializer.encode({ t: "pub", c: "events", d: event }));
343
+ const payload = eventPayload(event);
344
+ const envelope = {
345
+ event,
346
+ ts: Date.now(),
347
+ originNodeId: instanceId,
348
+ byteSize: payload === void 0 ? void 0 : encodedByteSize(serializer.encode(payload))
349
+ };
350
+ void adapter.publish(INSPECT + "events", serializer.encode({ t: "pub", c: "events", d: envelope }));
337
351
  }
338
352
  function joinChannel(conn, channel) {
339
353
  conn.channels.add(channel);
@@ -631,7 +645,8 @@ function createSuperLineServer(contract, opts) {
631
645
  connId: conn.id,
632
646
  name: info.name,
633
647
  ok: false,
634
- error: { code: e.code, message: e.message }
648
+ error: { code: e.code, message: e.message },
649
+ reqId: id
635
650
  });
636
651
  }
637
652
  }
@@ -650,7 +665,8 @@ function createSuperLineServer(contract, opts) {
650
665
  connId: conn.id,
651
666
  role: conn.role,
652
667
  name: frame.m,
653
- input: safeSnapshot(input)
668
+ input: safeSnapshot(input),
669
+ reqId: frame.i
654
670
  });
655
671
  const output = await handler(input, conn.ctx, conn);
656
672
  if (inspectorEnabled)
@@ -659,7 +675,8 @@ function createSuperLineServer(contract, opts) {
659
675
  connId: conn.id,
660
676
  name: frame.m,
661
677
  ok: true,
662
- output: safeSnapshot(output)
678
+ output: safeSnapshot(output),
679
+ reqId: frame.i
663
680
  });
664
681
  conn.send({ t: "res", i: frame.i, d: output });
665
682
  });
@@ -738,20 +755,29 @@ function createSuperLineServer(contract, opts) {
738
755
  if (inspectorEnabled) emitInspectorEvent({ type: "store.unsubscribe", connId: conn.id, store: frame.n, id: frame.id });
739
756
  }
740
757
  for (const [name, store] of Object.entries(storeMap)) {
758
+ const isSelf = store.clustering === "self";
741
759
  store.onChange((change) => {
760
+ const channel = STORE + name + ":" + change.id;
761
+ if (isSelf) {
762
+ const set = members.get(channel);
763
+ if (!set) return;
764
+ const payload = serializer.encode({ t: "sch", n: name, id: change.id, u: change.update, o: change.origin });
765
+ for (const conn of set) conn.sendRaw(payload);
766
+ return;
767
+ }
742
768
  if (relaying) return;
743
769
  void adapter.publish(
744
- STORE + name + ":" + change.id,
745
- serializer.encode({
746
- t: "sch",
747
- n: name,
748
- id: change.id,
749
- u: change.update,
750
- o: change.origin,
751
- nd: instanceId
752
- })
770
+ channel,
771
+ serializer.encode({ t: "sch", n: name, id: change.id, u: change.update, o: change.origin, nd: instanceId })
753
772
  );
754
773
  });
774
+ if (isSelf)
775
+ store.onDelete?.((id) => {
776
+ const set = members.get(STORE + name + ":" + id);
777
+ if (!set) return;
778
+ const payload = serializer.encode({ t: "sdel", n: name, id });
779
+ for (const conn of set) conn.sendRaw(payload);
780
+ });
755
781
  }
756
782
  function handleStoreRelay(channel, payload) {
757
783
  const set = members.get(channel);
@@ -765,6 +791,10 @@ function createSuperLineServer(contract, opts) {
765
791
  if (frame.nd === instanceId) return;
766
792
  const store = storeMap[frame.n];
767
793
  if (!store || store.clustering !== "relay") return;
794
+ if (frame.t === "sdel") {
795
+ void store.delete(frame.id);
796
+ return;
797
+ }
768
798
  relaying = true;
769
799
  try {
770
800
  void store.apply({ id: frame.id, update: frame.u, origin: frame.o });
@@ -872,7 +902,7 @@ function createSuperLineServer(contract, opts) {
872
902
  { once: true }
873
903
  );
874
904
  if (inspectorEnabled)
875
- emitInspectorEvent({ type: "msg.serverRequest", target: id, name, input: safeSnapshot(input) });
905
+ emitInspectorEvent({ type: "msg.serverRequest", target: id, name, input: safeSnapshot(input), reqId });
876
906
  const env = { p: "req", o: instanceId, i: reqId, m: name, d: input };
877
907
  void adapter.publish(CONN + id, serializer.encode(env));
878
908
  });
@@ -911,6 +941,11 @@ function createSuperLineServer(contract, opts) {
911
941
  },
912
942
  async delete(id) {
913
943
  await store.delete(id);
944
+ if (store.clustering !== "self")
945
+ void adapter.publish(
946
+ STORE + name + ":" + id,
947
+ serializer.encode({ t: "sdel", n: name, id, nd: instanceId })
948
+ );
914
949
  if (inspectorEnabled) emitInspectorEvent({ type: "store.delete", store: name, id });
915
950
  },
916
951
  list() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@super-line/server",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "type": "module",
5
5
  "description": "Typesafe WebSocket server for super-line — rooms, topics, middleware, pluggable adapters.",
6
6
  "license": "MIT",
@@ -47,7 +47,7 @@
47
47
  "access": "public"
48
48
  },
49
49
  "dependencies": {
50
- "@super-line/core": "^0.7.0"
50
+ "@super-line/core": "^0.8.0"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@chainsafe/libp2p-noise": "^17.0.0",
@@ -68,14 +68,14 @@
68
68
  "zeromq": "^6.0.0",
69
69
  "zod": "^3.24.1",
70
70
  "zod-to-json-schema": "^3.25.2",
71
- "@super-line/client": "0.6.0",
72
- "@super-line/adapter-rabbitmq": "0.5.0",
73
- "@super-line/adapter-redis": "0.5.0",
74
71
  "@super-line/adapter-libp2p": "0.5.0",
72
+ "@super-line/client": "0.7.0",
73
+ "@super-line/adapter-redis": "0.5.0",
74
+ "@super-line/adapter-rabbitmq": "0.5.0",
75
75
  "@super-line/transport-http": "0.5.0",
76
76
  "@super-line/adapter-zeromq": "0.5.0",
77
- "@super-line/transport-loopback": "0.5.0",
78
- "@super-line/transport-websocket": "0.5.0"
77
+ "@super-line/transport-websocket": "0.5.0",
78
+ "@super-line/transport-loopback": "0.5.0"
79
79
  },
80
80
  "optionalDependencies": {
81
81
  "@standard-community/standard-json": "^0.3.5"