@rvoh/psychic-workers 1.2.0 → 1.4.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.
@@ -13,6 +13,7 @@ const NoQueueForSpecifiedQueueName_js_1 = require("../error/background/NoQueueFo
13
13
  const NoQueueForSpecifiedWorkstream_js_1 = require("../error/background/NoQueueForSpecifiedWorkstream.js");
14
14
  const EnvInternal_js_1 = require("../helpers/EnvInternal.js");
15
15
  const index_js_1 = require("../psychic-app-workers/index.js");
16
+ const AttemtedToBackgroundEntireDreamModel_js_1 = require("../error/background/AttemtedToBackgroundEntireDreamModel.js");
16
17
  const nameToRedisQueueName_js_1 = require("./helpers/nameToRedisQueueName.js");
17
18
  const DEFAULT_CONCURRENCY = 10;
18
19
  /**
@@ -502,6 +503,11 @@ class Background {
502
503
  }
503
504
  // should be private, but public so we can test
504
505
  async _addToQueue(jobType, jobData, { delaySeconds, jobId, jobConfig, priority, groupId, }) {
506
+ ;
507
+ jobData.args.forEach(arg => {
508
+ if (arg instanceof dream_1.Dream)
509
+ throw new AttemtedToBackgroundEntireDreamModel_js_1.default(jobData.method, arg);
510
+ });
505
511
  // set this variable out side of the conditional so that
506
512
  // mismatches will raise exceptions even in tests
507
513
  const queueInstance = this.queueInstance(jobConfig);
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const dream_1 = require("@rvoh/dream");
4
+ class AttemtedToBackgroundEntireDreamModel extends Error {
5
+ method;
6
+ dream;
7
+ constructor(method, dream) {
8
+ super();
9
+ this.method = method;
10
+ this.dream = dream;
11
+ }
12
+ get message() {
13
+ const dreamClass = this.dream.constructor;
14
+ const primaryKey = dreamClass.primaryKey;
15
+ const sanitizedMethodName = (this.method ?? 'myMethod').replace(/^_/, '');
16
+ const className = this.dream.sanitizedConstructorName;
17
+ const instanceName = (0, dream_1.camelize)(className);
18
+ return `
19
+ Background \`${instanceName}.${primaryKey}\` (and \`${instanceName}.sanitizedConstructorName\`, if
20
+ the use case is polymorphic), not the entire Dream model. Then, in the
21
+ backgrounded method, find the model and return null if not found. For example:
22
+
23
+ \`\`\`
24
+ public async ${sanitizedMethodName}(${instanceName}: ${className}) {
25
+ await background('_${sanitizedMethodName}', ${instanceName}.${primaryKey})
26
+ }
27
+
28
+ public async _${sanitizedMethodName}(${instanceName}Id: string) {
29
+ const ${instanceName} = await User.find(${instanceName}Id)
30
+ if (!${instanceName}) return
31
+
32
+ ...
33
+ }
34
+ \`\`\`
35
+
36
+ This serves several purposes:
37
+ 1. Dramatically reduces the size of what gets stored in Redis
38
+ 2. Prevents sensitive data from being sent to Redis
39
+ 3. Does not retry the job if the corresponding model was deleted between when the
40
+ job was backgrounded and it was run
41
+ `;
42
+ }
43
+ }
44
+ exports.default = AttemtedToBackgroundEntireDreamModel;
@@ -1,4 +1,4 @@
1
- import { closeAllDbConnections, compact, pascalize } from '@rvoh/dream';
1
+ import { closeAllDbConnections, compact, Dream, pascalize } from '@rvoh/dream';
2
2
  import { PsychicApp } from '@rvoh/psychic';
3
3
  import { Job, Queue, Worker, } from 'bullmq';
4
4
  import ActivatingBackgroundWorkersWithoutDefaultWorkerConnection from '../error/background/ActivatingBackgroundWorkersWithoutDefaultWorkerConnection.js';
@@ -9,6 +9,7 @@ import NoQueueForSpecifiedQueueName from '../error/background/NoQueueForSpecifie
9
9
  import NoQueueForSpecifiedWorkstream from '../error/background/NoQueueForSpecifiedWorkstream.js';
10
10
  import EnvInternal from '../helpers/EnvInternal.js';
11
11
  import PsychicAppWorkers from '../psychic-app-workers/index.js';
12
+ import AttemtedToBackgroundEntireDreamModel from '../error/background/AttemtedToBackgroundEntireDreamModel.js';
12
13
  import nameToRedisQueueName from './helpers/nameToRedisQueueName.js';
13
14
  const DEFAULT_CONCURRENCY = 10;
14
15
  /**
@@ -498,6 +499,11 @@ export class Background {
498
499
  }
499
500
  // should be private, but public so we can test
500
501
  async _addToQueue(jobType, jobData, { delaySeconds, jobId, jobConfig, priority, groupId, }) {
502
+ ;
503
+ jobData.args.forEach(arg => {
504
+ if (arg instanceof Dream)
505
+ throw new AttemtedToBackgroundEntireDreamModel(jobData.method, arg);
506
+ });
501
507
  // set this variable out side of the conditional so that
502
508
  // mismatches will raise exceptions even in tests
503
509
  const queueInstance = this.queueInstance(jobConfig);
@@ -0,0 +1,41 @@
1
+ import { camelize } from '@rvoh/dream';
2
+ export default class AttemtedToBackgroundEntireDreamModel extends Error {
3
+ method;
4
+ dream;
5
+ constructor(method, dream) {
6
+ super();
7
+ this.method = method;
8
+ this.dream = dream;
9
+ }
10
+ get message() {
11
+ const dreamClass = this.dream.constructor;
12
+ const primaryKey = dreamClass.primaryKey;
13
+ const sanitizedMethodName = (this.method ?? 'myMethod').replace(/^_/, '');
14
+ const className = this.dream.sanitizedConstructorName;
15
+ const instanceName = camelize(className);
16
+ return `
17
+ Background \`${instanceName}.${primaryKey}\` (and \`${instanceName}.sanitizedConstructorName\`, if
18
+ the use case is polymorphic), not the entire Dream model. Then, in the
19
+ backgrounded method, find the model and return null if not found. For example:
20
+
21
+ \`\`\`
22
+ public async ${sanitizedMethodName}(${instanceName}: ${className}) {
23
+ await background('_${sanitizedMethodName}', ${instanceName}.${primaryKey})
24
+ }
25
+
26
+ public async _${sanitizedMethodName}(${instanceName}Id: string) {
27
+ const ${instanceName} = await User.find(${instanceName}Id)
28
+ if (!${instanceName}) return
29
+
30
+ ...
31
+ }
32
+ \`\`\`
33
+
34
+ This serves several purposes:
35
+ 1. Dramatically reduces the size of what gets stored in Redis
36
+ 2. Prevents sensitive data from being sent to Redis
37
+ 3. Does not retry the job if the corresponding model was deleted between when the
38
+ job was backgrounded and it was run
39
+ `;
40
+ }
41
+ }
@@ -0,0 +1,7 @@
1
+ import { Dream } from '@rvoh/dream';
2
+ export default class AttemtedToBackgroundEntireDreamModel extends Error {
3
+ private method;
4
+ private dream;
5
+ constructor(method: string | undefined, dream: Dream);
6
+ get message(): string;
7
+ }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "type": "module",
3
3
  "name": "@rvoh/psychic-workers",
4
4
  "description": "Background job system for Psychic applications",
5
- "version": "1.2.0",
5
+ "version": "1.4.0",
6
6
  "author": "RVO Health",
7
7
  "repository": {
8
8
  "type": "git",
@@ -43,34 +43,35 @@
43
43
  },
44
44
  "devDependencies": {
45
45
  "@eslint/js": "=9.0.0",
46
- "@rvoh/dream": "^1.4.0",
47
- "@rvoh/dream-spec-helpers": "^1.1.0",
48
- "@rvoh/psychic": "^1.2.0",
49
- "@rvoh/psychic-spec-helpers": "^1.0.1",
46
+ "@rvoh/dream": "^1.10.1",
47
+ "@rvoh/dream-spec-helpers": "^1.2.1",
48
+ "@rvoh/psychic": "^1.11.1",
49
+ "@rvoh/psychic-spec-helpers": "^1.1.3",
50
50
  "@socket.io/redis-adapter": "^8.3.0",
51
51
  "@socket.io/redis-emitter": "^5.1.0",
52
52
  "@types/express": "^4",
53
53
  "@types/node": "^22.5.1",
54
54
  "@types/pg": "^8",
55
- "@types/supertest": "^6.0.2",
55
+ "@types/supertest": "^6.0.3",
56
56
  "bullmq": "^5.52.0",
57
57
  "eslint": "^9.9.1",
58
58
  "express": "^4.21.2",
59
59
  "ioredis": "^5.4.1",
60
- "kysely": "^0.27.5",
60
+ "kysely": "^0.28.7",
61
61
  "kysely-codegen": "^0.17.0",
62
62
  "luxon-jest-matchers": "^0.1.14",
63
+ "openapi-typescript": "^7.9.1",
63
64
  "pg": "^8.13.1",
64
65
  "prettier": "^3.3.3",
65
66
  "socket.io": "^4.8.1",
66
67
  "socket.io-adapter": "^2.5.5",
67
- "supertest": "^7.0.0",
68
+ "supertest": "^7.1.4",
68
69
  "tslib": "^2.7.0",
69
70
  "tsx": "^4.19.3",
70
71
  "typedoc": "^0.26.6",
71
72
  "typescript": "^5.8.2",
72
73
  "typescript-eslint": "=7.18.0",
73
- "vitest": "^3.1.3"
74
+ "vitest": "^3.2.4"
74
75
  },
75
76
  "packageManager": "yarn@4.7.0"
76
77
  }