提交学习笔记专用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

62 lines
1.6 KiB

  1. 'use strict';
  2. const birpc = require('birpc');
  3. function createRPCServer(name, ws, functions, options = {}) {
  4. const event = `${name}:rpc`;
  5. const group = birpc.createBirpcGroup(
  6. functions,
  7. () => birpc.cachedMap(
  8. Array.from(ws?.clients || []),
  9. (channel) => {
  10. if (channel.socket.readyState === channel.socket.CLOSED)
  11. return void 0;
  12. return {
  13. on: (fn) => {
  14. function handler(data, source) {
  15. if (!source.socket)
  16. throw new Error("source.socket is undefined");
  17. if (channel.socket === source.socket)
  18. fn(data, source);
  19. }
  20. ws.on(event, handler);
  21. channel.socket.on("close", () => {
  22. ws.off(event, handler);
  23. });
  24. },
  25. post: (data) => {
  26. channel.send(event, data);
  27. }
  28. };
  29. }
  30. ).filter((c) => !!c),
  31. options
  32. );
  33. ws.on("connection", () => {
  34. group.updateChannels();
  35. });
  36. return group.broadcast;
  37. }
  38. function createRPCClient(name, hot, functions = {}, options = {}) {
  39. const event = `${name}:rpc`;
  40. const promise = Promise.resolve(hot).then((r) => {
  41. if (!r)
  42. console.warn("[vite-hot-client] Received undefined hot context, RPC calls are ignored");
  43. return r;
  44. });
  45. return birpc.createBirpc(
  46. functions,
  47. {
  48. ...options,
  49. on: async (fn) => {
  50. (await promise)?.on(event, fn);
  51. },
  52. post: async (data) => {
  53. (await promise)?.send(event, data);
  54. }
  55. }
  56. );
  57. }
  58. exports.createRPCClient = createRPCClient;
  59. exports.createRPCServer = createRPCServer;