@rvoh/psychic-websockets 0.5.0 → 2.0.0-alpha.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.
@@ -1,13 +1,13 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const dream_1 = require("@rvoh/dream");
4
- const psychic_1 = require("@rvoh/psychic");
5
- const redis_adapter_1 = require("@socket.io/redis-adapter");
6
- const socketio = require("socket.io");
7
- const MissingWsRedisConnection_js_1 = require("../error/ws/MissingWsRedisConnection.js");
8
- const EnvInternal_js_1 = require("../helpers/EnvInternal.js");
9
- const index_js_1 = require("../psychic-app-websockets/index.js");
10
- class Cable {
1
+ import { DreamCLI } from '@rvoh/dream';
2
+ import { PsychicApp, PsychicServer } from '@rvoh/psychic';
3
+ import { PsychicLogos } from '@rvoh/psychic/internal';
4
+ import { colorize } from '@rvoh/psychic/utils';
5
+ import { createAdapter } from '@socket.io/redis-adapter';
6
+ import * as socketio from 'socket.io';
7
+ import MissingWsRedisConnection from '../error/ws/MissingWsRedisConnection.js';
8
+ import EnvInternal from '../helpers/EnvInternal.js';
9
+ import PsychicAppWebsockets from '../psychic-app-websockets/index.js';
10
+ export default class Cable {
11
11
  app;
12
12
  io;
13
13
  httpServer;
@@ -28,7 +28,7 @@ class Cable {
28
28
  return;
29
29
  // for socket.io, we have to circumvent the normal process for starting a
30
30
  // psychic server so that we can bind socket.io to the http instance.
31
- this.httpServer = psychic_1.PsychicServer.createPsychicHttpInstance(this.app, this.config.psychicApp.sslCredentials);
31
+ this.httpServer = PsychicServer.createPsychicHttpInstance(this.app, this.config.psychicApp.sslCredentials);
32
32
  this.io = new socketio.Server(this.httpServer, { cors: this.config.psychicApp.corsOptions });
33
33
  }
34
34
  /**
@@ -47,7 +47,7 @@ class Cable {
47
47
  }
48
48
  }
49
49
  catch (error) {
50
- if (EnvInternal_js_1.default.boolean('PSYCHIC_DANGEROUSLY_PERMIT_WS_EXCEPTIONS'))
50
+ if (EnvInternal.boolean('PSYCHIC_DANGEROUSLY_PERMIT_WS_EXCEPTIONS'))
51
51
  throw error;
52
52
  else {
53
53
  ;
@@ -67,7 +67,7 @@ class Cable {
67
67
  }
68
68
  });
69
69
  this.bindToRedis();
70
- const psychicAppWebsockets = index_js_1.default.getOrFail();
70
+ const psychicAppWebsockets = PsychicAppWebsockets.getOrFail();
71
71
  await this.listen({
72
72
  port: parseInt((port || psychicAppWebsockets.psychicApp.port).toString()),
73
73
  });
@@ -99,7 +99,7 @@ class Cable {
99
99
  async listen({ port }) {
100
100
  return new Promise(accept => {
101
101
  this.httpServer.listen(port, () => {
102
- if (!EnvInternal_js_1.default.isTest) {
102
+ if (!EnvInternal.isTest) {
103
103
  welcomeMessage({ port });
104
104
  }
105
105
  accept(true);
@@ -115,39 +115,38 @@ class Cable {
115
115
  const pubClient = this.config.websocketOptions.connection;
116
116
  const subClient = this.config.websocketOptions.subConnection;
117
117
  if (!pubClient || !subClient)
118
- throw new MissingWsRedisConnection_js_1.default();
118
+ throw new MissingWsRedisConnection();
119
119
  this.redisConnections.push(pubClient);
120
120
  this.redisConnections.push(subClient);
121
121
  pubClient.on('error', error => {
122
- index_js_1.default.log('PUB CLIENT ERROR', error);
122
+ PsychicAppWebsockets.log('PUB CLIENT ERROR', error);
123
123
  });
124
124
  subClient.on('error', error => {
125
- index_js_1.default.log('sub CLIENT ERROR', error);
125
+ PsychicAppWebsockets.log('sub CLIENT ERROR', error);
126
126
  });
127
127
  try {
128
- this.io.adapter((0, redis_adapter_1.createAdapter)(pubClient, subClient));
128
+ this.io.adapter(createAdapter(pubClient, subClient));
129
129
  }
130
130
  catch (error) {
131
- index_js_1.default.log('FAILED TO ADAPT', error);
131
+ PsychicAppWebsockets.log('FAILED TO ADAPT', error);
132
132
  }
133
133
  }
134
134
  }
135
- exports.default = Cable;
136
135
  function welcomeMessage({ port }) {
137
- if (EnvInternal_js_1.default.isDevelopment) {
138
- dream_1.DreamCLI.logger.log((0, psychic_1.colorize)(psychic_1.PsychicLogos.asciiLogo(), { color: 'greenBright' }), {
136
+ if (EnvInternal.isDevelopment) {
137
+ DreamCLI.logger.log(colorize(PsychicLogos.asciiLogo(), { color: 'greenBright' }), {
139
138
  logPrefix: '',
140
139
  });
141
- dream_1.DreamCLI.logger.log('', { logPrefix: '' });
142
- dream_1.DreamCLI.logger.log((0, psychic_1.colorize)('✺ ' + psychic_1.PsychicApp.getOrFail().appName, { color: 'greenBright' }), {
140
+ DreamCLI.logger.log('', { logPrefix: '' });
141
+ DreamCLI.logger.log(colorize('✺ ' + PsychicApp.getOrFail().appName, { color: 'greenBright' }), {
143
142
  logPrefix: '',
144
143
  });
145
- dream_1.DreamCLI.logger.log((0, psychic_1.colorize)(`└─ http://localhost:${port.toString()}`, { color: 'greenBright' }), {
144
+ DreamCLI.logger.log(colorize(`└─ http://localhost:${port.toString()}`, { color: 'greenBright' }), {
146
145
  logPrefix: '',
147
146
  });
148
- dream_1.DreamCLI.logger.log('', { logPrefix: '' });
147
+ DreamCLI.logger.log('', { logPrefix: '' });
149
148
  }
150
149
  else {
151
- dream_1.DreamCLI.logger.log(`psychic dev server started at port ${port} with websockets`);
150
+ DreamCLI.logger.log(`psychic dev server started at port ${port} with websockets`);
152
151
  }
153
152
  }
@@ -1,6 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = redisWsKey;
4
- function redisWsKey(websocketId, redisKeyPrefix) {
1
+ export default function redisWsKey(websocketId, redisKeyPrefix) {
5
2
  return `${redisKeyPrefix}:${websocketId}:socket_ids`;
6
3
  }
@@ -1,12 +1,11 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const dream_1 = require("@rvoh/dream");
4
- const redis_emitter_1 = require("@socket.io/redis-emitter");
5
- const InvalidWsPathError_js_1 = require("../error/ws/InvalidWsPathError.js");
6
- const EnvInternal_js_1 = require("../helpers/EnvInternal.js");
7
- const index_js_1 = require("../psychic-app-websockets/index.js");
8
- const redisWsKey_js_1 = require("./redisWsKey.js");
9
- class Ws {
1
+ import { DateTime, Dream } from '@rvoh/dream';
2
+ import { uniq } from '@rvoh/dream/utils';
3
+ import { Emitter } from '@socket.io/redis-emitter';
4
+ import InvalidWsPathError from '../error/ws/InvalidWsPathError.js';
5
+ import EnvInternal from '../helpers/EnvInternal.js';
6
+ import PsychicAppWebsockets from '../psychic-app-websockets/index.js';
7
+ import redisWsKey from './redisWsKey.js';
8
+ export default class Ws {
10
9
  allowedPaths;
11
10
  /**
12
11
  * @internal
@@ -57,10 +56,10 @@ class Ws {
57
56
  * @param redisKeyPrefix - (optional) the prefix you wish to use to couple to this id (defaults to 'user')
58
57
  */
59
58
  static async register(socket, id, redisKeyPrefix = 'user') {
60
- const psychicWebsocketsApp = index_js_1.default.getOrFail();
59
+ const psychicWebsocketsApp = PsychicAppWebsockets.getOrFail();
61
60
  const redisClient = psychicWebsocketsApp.websocketOptions.connection;
62
61
  const websocketId = idOrDreamToId(id);
63
- const redisKey = (0, redisWsKey_js_1.default)(websocketId, redisKeyPrefix);
62
+ const redisKey = redisWsKey(websocketId, redisKeyPrefix);
64
63
  const socketIdsToKeep = await redisClient.lrange(redisKey, -2, -1);
65
64
  await redisClient
66
65
  .multi()
@@ -68,8 +67,8 @@ class Ws {
68
67
  .rpush(redisKey, ...socketIdsToKeep, socket.id)
69
68
  .expireat(redisKey,
70
69
  // TODO: make this configurable in non-test environments
71
- dream_1.DateTime.now()
72
- .plus(EnvInternal_js_1.default.isTest ? { seconds: 15 } : { day: 1 })
70
+ DateTime.now()
71
+ .plus(EnvInternal.isTest ? { seconds: 15 } : { day: 1 })
73
72
  .toSeconds())
74
73
  .exec();
75
74
  socket.on('disconnect', async () => {
@@ -111,9 +110,9 @@ class Ws {
111
110
  boot() {
112
111
  if (this.booted)
113
112
  return;
114
- const psychicWebsocketsApp = index_js_1.default.getOrFail();
113
+ const psychicWebsocketsApp = PsychicAppWebsockets.getOrFail();
115
114
  this.redisClient = psychicWebsocketsApp.websocketOptions.connection;
116
- this.io = new redis_emitter_1.Emitter(this.redisClient).of(this.namespace);
115
+ this.io = new Emitter(this.redisClient).of(this.namespace);
117
116
  this.booted = true;
118
117
  }
119
118
  /**
@@ -127,7 +126,7 @@ class Ws {
127
126
  // eslint-disable-next-line
128
127
  data = {}) {
129
128
  if (this.allowedPaths.length && !this.allowedPaths.includes(path))
130
- throw new InvalidWsPathError_js_1.default(path);
129
+ throw new InvalidWsPathError(path);
131
130
  this.boot();
132
131
  const socketIds = await this.findSocketIds(idOrDreamToId(id));
133
132
  for (const socketId of socketIds) {
@@ -141,7 +140,7 @@ class Ws {
141
140
  */
142
141
  async findSocketIds(userId) {
143
142
  this.boot();
144
- return (0, dream_1.uniq)(await this.redisClient.lrange(this.redisKey(userId), 0, -1));
143
+ return uniq(await this.redisClient.lrange(this.redisKey(userId), 0, -1));
145
144
  }
146
145
  /**
147
146
  * @internal
@@ -150,10 +149,9 @@ class Ws {
150
149
  * when this Ws instance was constructed.
151
150
  */
152
151
  redisKey(userId) {
153
- return (0, redisWsKey_js_1.default)(userId, this.redisKeyPrefix);
152
+ return redisWsKey(userId, this.redisKeyPrefix);
154
153
  }
155
154
  }
156
- exports.default = Ws;
157
155
  function idOrDreamToId(id) {
158
- return id instanceof dream_1.Dream ? id.primaryKeyValue().toString() : id.toString();
156
+ return id instanceof Dream ? id.primaryKeyValue().toString() : id.toString();
159
157
  }
@@ -1,6 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- class InvalidWsPathError extends Error {
1
+ export default class InvalidWsPathError extends Error {
4
2
  invalidPath;
5
3
  constructor(invalidPath) {
6
4
  super();
@@ -12,4 +10,3 @@ class InvalidWsPathError extends Error {
12
10
  `;
13
11
  }
14
12
  }
15
- exports.default = InvalidWsPathError;
@@ -1,6 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- class MissingWsRedisConnection extends Error {
1
+ export default class MissingWsRedisConnection extends Error {
4
2
  get message() {
5
3
  return `
6
4
  No websocket redis connection was found, even though
@@ -29,4 +27,3 @@ export default async (psy: PsychicApp) => {
29
27
  `;
30
28
  }
31
29
  }
32
- exports.default = MissingWsRedisConnection;
@@ -1,5 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const dream_1 = require("@rvoh/dream");
4
- const EnvInternal = new dream_1.Env();
5
- exports.default = EnvInternal;
1
+ import { Env } from '@rvoh/dream';
2
+ const EnvInternal = new Env();
3
+ export default EnvInternal;
@@ -1,9 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PsychicAppWebsockets = exports.Ws = exports.Cable = void 0;
4
- var index_js_1 = require("./cable/index.js");
5
- Object.defineProperty(exports, "Cable", { enumerable: true, get: function () { return index_js_1.default; } });
6
- var ws_js_1 = require("./cable/ws.js");
7
- Object.defineProperty(exports, "Ws", { enumerable: true, get: function () { return ws_js_1.default; } });
8
- var index_js_2 = require("./psychic-app-websockets/index.js");
9
- Object.defineProperty(exports, "PsychicAppWebsockets", { enumerable: true, get: function () { return index_js_2.default; } });
1
+ export { default as Cable } from './cable/index.js';
2
+ export { default as Ws } from './cable/ws.js';
3
+ export { default as PsychicAppWebsockets } from './psychic-app-websockets/index.js';
@@ -1,16 +1,11 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.cachePsychicAppWebsockets = cachePsychicAppWebsockets;
4
- exports.getCachedPsychicAppWebsockets = getCachedPsychicAppWebsockets;
5
- exports.getCachedPsychicAppWebsocketsOrFail = getCachedPsychicAppWebsocketsOrFail;
6
1
  let _psychicAppWebsockets = undefined;
7
- function cachePsychicAppWebsockets(psychicAppWebsockets) {
2
+ export function cachePsychicAppWebsockets(psychicAppWebsockets) {
8
3
  _psychicAppWebsockets = psychicAppWebsockets;
9
4
  }
10
- function getCachedPsychicAppWebsockets() {
5
+ export function getCachedPsychicAppWebsockets() {
11
6
  return _psychicAppWebsockets;
12
7
  }
13
- function getCachedPsychicAppWebsocketsOrFail() {
8
+ export function getCachedPsychicAppWebsocketsOrFail() {
14
9
  if (!_psychicAppWebsockets)
15
10
  throw new Error('must call `cachePsychicAppWebsockets` before loading cached psychic application websockets');
16
11
  return _psychicAppWebsockets;
@@ -1,8 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const index_js_1 = require("../cable/index.js");
4
- const cache_js_1 = require("./cache.js");
5
- class PsychicAppWebsockets {
1
+ import Cable from '../cable/index.js';
2
+ import { cachePsychicAppWebsockets, getCachedPsychicAppWebsocketsOrFail } from './cache.js';
3
+ export default class PsychicAppWebsockets {
6
4
  static async init(psychicApp, cb) {
7
5
  const psychicWsApp = new PsychicAppWebsockets(psychicApp);
8
6
  await cb(psychicWsApp);
@@ -15,12 +13,12 @@ class PsychicAppWebsockets {
15
13
  }
16
14
  });
17
15
  psychicApp.override('server:start', async (psychicServer, { port }) => {
18
- const cable = new index_js_1.default(psychicServer.expressApp, psychicWsApp);
16
+ const cable = new Cable(psychicServer.expressApp, psychicWsApp);
19
17
  await cable.start(port);
20
18
  psychicServer.attach('cable', cable);
21
19
  return cable.httpServer;
22
20
  });
23
- (0, cache_js_1.cachePsychicAppWebsockets)(psychicWsApp);
21
+ cachePsychicAppWebsockets(psychicWsApp);
24
22
  return psychicWsApp;
25
23
  }
26
24
  /**
@@ -30,7 +28,7 @@ class PsychicAppWebsockets {
30
28
  * The psychic application can be set by calling PsychicApp#init
31
29
  */
32
30
  static getOrFail() {
33
- return (0, cache_js_1.getCachedPsychicAppWebsocketsOrFail)();
31
+ return getCachedPsychicAppWebsocketsOrFail();
34
32
  }
35
33
  psychicApp;
36
34
  static log(...args) {
@@ -83,4 +81,3 @@ class PsychicAppWebsockets {
83
81
  }
84
82
  }
85
83
  }
86
- exports.default = PsychicAppWebsockets;
@@ -1,5 +1,7 @@
1
1
  import { DreamCLI } from '@rvoh/dream';
2
- import { colorize, PsychicApp, PsychicLogos, PsychicServer } from '@rvoh/psychic';
2
+ import { PsychicApp, PsychicServer } from '@rvoh/psychic';
3
+ import { PsychicLogos } from '@rvoh/psychic/internal';
4
+ import { colorize } from '@rvoh/psychic/utils';
3
5
  import { createAdapter } from '@socket.io/redis-adapter';
4
6
  import * as socketio from 'socket.io';
5
7
  import MissingWsRedisConnection from '../error/ws/MissingWsRedisConnection.js';
@@ -1,4 +1,5 @@
1
- import { DateTime, Dream, uniq } from '@rvoh/dream';
1
+ import { DateTime, Dream } from '@rvoh/dream';
2
+ import { uniq } from '@rvoh/dream/utils';
2
3
  import { Emitter } from '@socket.io/redis-emitter';
3
4
  import InvalidWsPathError from '../error/ws/InvalidWsPathError.js';
4
5
  import EnvInternal from '../helpers/EnvInternal.js';
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "type": "module",
3
3
  "name": "@rvoh/psychic-websockets",
4
4
  "description": "Websocket system for Psychic applications",
5
- "version": "0.5.0",
5
+ "version": "2.0.0-alpha.1",
6
6
  "author": "RVO Health",
7
7
  "repository": {
8
8
  "type": "git",
@@ -29,6 +29,7 @@
29
29
  "psy:js": "node ./dist/test-app/src/cli/index.js",
30
30
  "psy:ts": "tsx ./test-app/src/cli/index.ts",
31
31
  "build": "echo \"building cjs...\" && rm -rf dist && npx tsc -p ./tsconfig.cjs.build.json && echo \"building esm...\" && npx tsc -p ./tsconfig.esm.build.json",
32
+ "build:test-app": "rm -rf dist && echo \"building test app to esm...\" && npx tsc -p ./tsconfig.esm.build.test-app.json && echo \"building test app to cjs...\" && npx tsc -p ./tsconfig.cjs.build.test-app.json",
32
33
  "uspec": "vitest --config ./spec/unit/vite.config.ts",
33
34
  "fspec": "vitest run --config=./spec/features/vite.config.ts",
34
35
  "fspec:hanging": "vitest run --config=./spec/features/vite.config.ts --reporter=hanging-process",
@@ -48,9 +49,9 @@
48
49
  },
49
50
  "devDependencies": {
50
51
  "@eslint/js": "=9.0.0",
51
- "@rvoh/dream": "^1.10.1",
52
+ "@rvoh/dream": "^2.0.0-alpha.1",
52
53
  "@rvoh/dream-spec-helpers": "^1.2.1",
53
- "@rvoh/psychic": "^1.11.1",
54
+ "@rvoh/psychic": "^2.0.0-alpha.1",
54
55
  "@rvoh/psychic-spec-helpers": "^1.1.3",
55
56
  "@socket.io/redis-adapter": "^8.3.0",
56
57
  "@socket.io/redis-emitter": "^5.1.0",
@@ -78,7 +79,7 @@
78
79
  "typedoc": "^0.26.6",
79
80
  "typescript": "^5.8.2",
80
81
  "typescript-eslint": "=7.18.0",
81
- "vitest": "^3.2.0"
82
+ "vitest": "^3.2.4"
82
83
  },
83
84
  "packageManager": "yarn@4.7.0",
84
85
  "dependencies": {