velocious 1.0.558 → 1.0.559
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/README.md +1 -1
- package/build/background-jobs/store.js +262 -16
- package/build/background-jobs/web/authorization.js +5 -4
- package/build/background-jobs/web/controller.js +13 -16
- package/build/background-jobs/web/counts-channel.js +79 -0
- package/build/background-jobs/web/index.js +2 -0
- package/build/background-jobs/web/registry.js +1 -1
- package/build/src/background-jobs/store.d.ts +79 -0
- package/build/src/background-jobs/store.d.ts.map +1 -1
- package/build/src/background-jobs/store.js +235 -17
- package/build/src/background-jobs/web/authorization.d.ts +5 -3
- package/build/src/background-jobs/web/authorization.d.ts.map +1 -1
- package/build/src/background-jobs/web/authorization.js +6 -5
- package/build/src/background-jobs/web/controller.d.ts.map +1 -1
- package/build/src/background-jobs/web/controller.js +14 -15
- package/build/src/background-jobs/web/counts-channel.d.ts +31 -0
- package/build/src/background-jobs/web/counts-channel.d.ts.map +1 -0
- package/build/src/background-jobs/web/counts-channel.js +71 -0
- package/build/src/background-jobs/web/index.d.ts.map +1 -1
- package/build/src/background-jobs/web/index.js +3 -1
- package/build/src/background-jobs/web/registry.d.ts +1 -1
- package/build/src/background-jobs/web/registry.d.ts.map +1 -1
- package/build/src/background-jobs/web/registry.js +2 -2
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/background-jobs/store.js +262 -16
- package/src/background-jobs/web/authorization.js +5 -4
- package/src/background-jobs/web/controller.js +13 -16
- package/src/background-jobs/web/counts-channel.js +79 -0
- package/src/background-jobs/web/index.js +2 -0
- package/src/background-jobs/web/registry.js +1 -1
|
@@ -99,7 +99,11 @@ export default class VelociousBackgroundJobsWebController extends Controller {
|
|
|
99
99
|
*/
|
|
100
100
|
async health() {
|
|
101
101
|
await this._respond(async () => {
|
|
102
|
-
await this.render({json: {
|
|
102
|
+
await this.render({json: {
|
|
103
|
+
capabilities: {backgroundJobCountDeltas: 1},
|
|
104
|
+
ok: true,
|
|
105
|
+
service: "velocious-background-jobs"
|
|
106
|
+
}})
|
|
103
107
|
})
|
|
104
108
|
}
|
|
105
109
|
|
|
@@ -109,22 +113,15 @@ export default class VelociousBackgroundJobsWebController extends Controller {
|
|
|
109
113
|
*/
|
|
110
114
|
async stats() {
|
|
111
115
|
await this._respond(async () => {
|
|
112
|
-
const
|
|
113
|
-
/**
|
|
114
|
-
* By status.
|
|
115
|
-
* @type {Record<string, number>} */
|
|
116
|
-
const byStatus = {}
|
|
117
|
-
let total = 0
|
|
118
|
-
|
|
119
|
-
for (const status of DASHBOARD_STATUSES) {
|
|
120
|
-
byStatus[status] = counts[status] || 0
|
|
121
|
-
}
|
|
116
|
+
const snapshot = await this._store().countSnapshot()
|
|
122
117
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
118
|
+
await this.render({json: {
|
|
119
|
+
capabilities: {backgroundJobCountDeltas: 1},
|
|
120
|
+
counts: snapshot.counts,
|
|
121
|
+
generatedAtMs: Date.now(),
|
|
122
|
+
revision: snapshot.revision,
|
|
123
|
+
total: snapshot.total
|
|
124
|
+
}})
|
|
128
125
|
})
|
|
129
126
|
}
|
|
130
127
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import {BACKGROUND_JOB_COUNTS_CHANNEL} from "../store.js"
|
|
4
|
+
import VelociousWebsocketChannel from "../../http-server/websocket-channel.js"
|
|
5
|
+
import {authorizeJobsRequest} from "./authorization.js"
|
|
6
|
+
import {getJobsMount} from "./registry.js"
|
|
7
|
+
import {normalizeMountPrefix} from "./path-matcher.js"
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Authorized dashboard count-delta channel. Clients subscribe with the mount
|
|
11
|
+
* path and their normal bearer token as `authenticationToken`.
|
|
12
|
+
*/
|
|
13
|
+
export default class BackgroundJobCountsChannel extends VelociousWebsocketChannel {
|
|
14
|
+
/**
|
|
15
|
+
* Authorizes the subscription.
|
|
16
|
+
* @returns {Promise<boolean>} Whether the mount's normal dashboard authorization allows the subscription.
|
|
17
|
+
*/
|
|
18
|
+
async canSubscribe() {
|
|
19
|
+
if (typeof this.params.mountAt !== "string") return false
|
|
20
|
+
|
|
21
|
+
const mountAt = normalizeMountPrefix(this.params.mountAt)
|
|
22
|
+
const options = getJobsMount(this.session.configuration, mountAt)
|
|
23
|
+
|
|
24
|
+
if (!options || !this.session.upgradeRequest) return false
|
|
25
|
+
|
|
26
|
+
const token = typeof this.params.authenticationToken === "string"
|
|
27
|
+
? this.params.authenticationToken
|
|
28
|
+
: null
|
|
29
|
+
const ability = await this.session.configuration.resolveAbility({
|
|
30
|
+
params: this.params,
|
|
31
|
+
request: this.session.upgradeRequest
|
|
32
|
+
})
|
|
33
|
+
const authorized = await authorizeJobsRequest({
|
|
34
|
+
ability,
|
|
35
|
+
configuration: this.session.configuration,
|
|
36
|
+
options,
|
|
37
|
+
request: this.session.upgradeRequest,
|
|
38
|
+
token
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
if (!authorized) return false
|
|
42
|
+
|
|
43
|
+
this.databaseIdentifier = options.databaseIdentifier
|
|
44
|
+
|| this.session.configuration.getBackgroundJobsConfig().databaseIdentifier
|
|
45
|
+
|| "default"
|
|
46
|
+
|
|
47
|
+
return true
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Matches only events from the database selected by the authorized mount.
|
|
52
|
+
* @param {import("../../http-server/websocket-channel.js").WebsocketJsonValue} broadcastParams - Publisher scope.
|
|
53
|
+
* @returns {boolean} Whether this subscription should receive the event.
|
|
54
|
+
*/
|
|
55
|
+
matches(broadcastParams) {
|
|
56
|
+
if (!broadcastParams || typeof broadcastParams !== "object" || Array.isArray(broadcastParams)) return false
|
|
57
|
+
|
|
58
|
+
return String(/** @type {Record<string, ?>} */ (broadcastParams).databaseIdentifier) === this.databaseIdentifier
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Builds diagnostics.
|
|
63
|
+
* @returns {Record<string, string>} Non-sensitive diagnostics.
|
|
64
|
+
*/
|
|
65
|
+
debugSnapshot() {
|
|
66
|
+
return {databaseIdentifier: this.databaseIdentifier}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** @type {string} */
|
|
70
|
+
databaseIdentifier = ""
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Registers the framework channel used by mounted jobs dashboards.
|
|
74
|
+
* @param {import("../../configuration.js").default} configuration - Configuration.
|
|
75
|
+
*/
|
|
76
|
+
static register(configuration) {
|
|
77
|
+
configuration.registerWebsocketChannel(BACKGROUND_JOB_COUNTS_CHANNEL, this)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
3
|
import VelociousBackgroundJobsWebController from "./controller.js"
|
|
4
|
+
import BackgroundJobCountsChannel from "./counts-channel.js"
|
|
4
5
|
import {matchJobsApiPath, normalizeMountPrefix} from "./path-matcher.js"
|
|
5
6
|
import {registerJobsMount} from "./registry.js"
|
|
6
7
|
|
|
@@ -40,6 +41,7 @@ export default class VelociousBackgroundJobsApi {
|
|
|
40
41
|
const prefix = normalizeMountPrefix(at)
|
|
41
42
|
|
|
42
43
|
registerJobsMount(configuration, prefix, {accessTokens, allowedOrigins, authorize, databaseIdentifier, redactArgs})
|
|
44
|
+
BackgroundJobCountsChannel.register(configuration)
|
|
43
45
|
|
|
44
46
|
configuration.addRouteResolverHook(({currentPath, request}) => {
|
|
45
47
|
const match = matchJobsApiPath({method: request.httpMethod(), path: currentPath, prefix})
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* JobsMountOptions type.
|
|
5
5
|
* @typedef {object} JobsMountOptions
|
|
6
|
-
* @property {(args: {request: import("../../http-server/client/request.js").default, ability: (import("../../authorization/ability.js").default | undefined), token: (string | null), configuration: import("../../configuration.js").default}) => (boolean | void | Promise<boolean | void>)} [authorize] - Authorization callback. Return true to allow the request.
|
|
6
|
+
* @property {(args: {request: import("../../http-server/client/request.js").default | import("../../http-server/client/websocket-request.js").default, ability: (import("../../authorization/ability.js").default | undefined), token: (string | null), configuration: import("../../configuration.js").default}) => (boolean | void | Promise<boolean | void>)} [authorize] - Authorization callback. Return true to allow the request.
|
|
7
7
|
* @property {string[]} [accessTokens] - Bearer tokens accepted for cross-origin/native access.
|
|
8
8
|
* @property {string[]} [allowedOrigins] - Origins allowed for cross-origin browser access.
|
|
9
9
|
* @property {boolean} [redactArgs] - When true, job arguments are omitted from API responses.
|