velocious 1.0.515 → 1.0.516
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 +3 -3
- package/build/background-jobs/cron-expression.js +9 -9
- package/build/background-jobs/forked-runner-child.js +1 -1
- package/build/background-jobs/job-runner.js +21 -15
- package/build/background-jobs/json-socket.js +4 -0
- package/build/background-jobs/main.js +180 -18
- package/build/background-jobs/status-reporter.js +12 -5
- package/build/background-jobs/store.js +132 -50
- package/build/background-jobs/types.js +11 -3
- package/build/background-jobs/worker.js +9 -5
- package/build/beacon/client.js +13 -6
- package/build/configuration.js +31 -29
- package/build/controller.js +9 -3
- package/build/database/drivers/sqlite/base.js +1 -1
- package/build/database/drivers/sqlite/index.js +15 -14
- package/build/database/migrations-ledger.js +16 -16
- package/build/database/query/where-model-class-hash.js +2 -0
- package/build/database/query/with-count.js +1 -1
- package/build/database/record/acts-as-list.js +2 -2
- package/build/database/record/auditing.js +23 -6
- package/build/database/record/index.js +7 -7
- package/build/database/record/validators/uniqueness.js +3 -3
- package/build/database/tenants/data-copier.js +23 -23
- package/build/database/tenants/schema-cloner.js +27 -27
- package/build/environment-handlers/browser.js +0 -1
- package/build/environment-handlers/node/cli/commands/background-jobs-runner.js +2 -1
- package/build/environment-handlers/node/cli/commands/lint/relationships.js +2 -2
- package/build/environment-handlers/node.js +1 -1
- package/build/frontend-model-controller.js +26 -18
- package/build/frontend-models/base.js +5 -5
- package/build/frontend-models/query.js +12 -12
- package/build/http-server/client/index.js +61 -15
- package/build/http-server/client/response.js +17 -1
- package/build/http-server/client/websocket-session.js +13 -13
- package/build/http-server/server-client.js +96 -0
- package/build/http-server/websocket-channel.js +12 -11
- package/build/http-server/websocket-connection.js +12 -11
- package/build/http-server/websocket-events-host.js +1 -1
- package/build/http-server/worker-handler/in-process.js +48 -9
- package/build/http-server/worker-handler/index.js +67 -7
- package/build/http-server/worker-handler/worker-thread.js +68 -0
- package/build/src/background-jobs/cron-expression.d.ts +2 -2
- package/build/src/background-jobs/cron-expression.js +10 -10
- package/build/src/background-jobs/forked-runner-child.js +2 -2
- package/build/src/background-jobs/job-runner.d.ts +5 -1
- package/build/src/background-jobs/job-runner.d.ts.map +1 -1
- package/build/src/background-jobs/job-runner.js +22 -16
- package/build/src/background-jobs/json-socket.d.ts +4 -0
- package/build/src/background-jobs/json-socket.d.ts.map +1 -1
- package/build/src/background-jobs/json-socket.js +5 -1
- package/build/src/background-jobs/main.d.ts +62 -10
- package/build/src/background-jobs/main.d.ts.map +1 -1
- package/build/src/background-jobs/main.js +171 -19
- package/build/src/background-jobs/status-reporter.d.ts +6 -2
- package/build/src/background-jobs/status-reporter.d.ts.map +1 -1
- package/build/src/background-jobs/status-reporter.js +13 -6
- package/build/src/background-jobs/store.d.ts +48 -25
- package/build/src/background-jobs/store.d.ts.map +1 -1
- package/build/src/background-jobs/store.js +123 -50
- package/build/src/background-jobs/types.d.ts +36 -3
- package/build/src/background-jobs/types.d.ts.map +1 -1
- package/build/src/background-jobs/types.js +12 -4
- package/build/src/background-jobs/worker.d.ts +7 -5
- package/build/src/background-jobs/worker.d.ts.map +1 -1
- package/build/src/background-jobs/worker.js +10 -6
- package/build/src/beacon/client.d.ts +6 -3
- package/build/src/beacon/client.d.ts.map +1 -1
- package/build/src/beacon/client.js +14 -7
- package/build/src/configuration-types.d.ts +1 -1
- package/build/src/configuration.d.ts +31 -29
- package/build/src/configuration.d.ts.map +1 -1
- package/build/src/configuration.js +32 -30
- package/build/src/controller.d.ts +3 -0
- package/build/src/controller.d.ts.map +1 -1
- package/build/src/controller.js +9 -4
- package/build/src/database/drivers/sqlite/base.js +2 -2
- package/build/src/database/drivers/sqlite/index.d.ts +7 -6
- package/build/src/database/drivers/sqlite/index.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/index.js +16 -15
- package/build/src/database/migrations-ledger.d.ts +16 -16
- package/build/src/database/migrations-ledger.js +17 -17
- package/build/src/database/query/where-model-class-hash.d.ts.map +1 -1
- package/build/src/database/query/where-model-class-hash.js +3 -1
- package/build/src/database/query/with-count.js +2 -2
- package/build/src/database/record/acts-as-list.js +3 -3
- package/build/src/database/record/auditing.d.ts +1 -1
- package/build/src/database/record/auditing.d.ts.map +1 -1
- package/build/src/database/record/auditing.js +24 -7
- package/build/src/database/record/index.d.ts +7 -7
- package/build/src/database/record/index.js +8 -8
- package/build/src/database/record/validators/uniqueness.d.ts +3 -3
- package/build/src/database/record/validators/uniqueness.js +4 -4
- package/build/src/database/tenants/data-copier.d.ts +18 -18
- package/build/src/database/tenants/data-copier.js +24 -24
- package/build/src/database/tenants/schema-cloner.d.ts +27 -27
- package/build/src/database/tenants/schema-cloner.js +28 -28
- package/build/src/environment-handlers/browser.d.ts +9 -0
- package/build/src/environment-handlers/browser.d.ts.map +1 -1
- package/build/src/environment-handlers/browser.js +1 -2
- package/build/src/environment-handlers/node/cli/commands/background-jobs-runner.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/background-jobs-runner.js +3 -2
- package/build/src/environment-handlers/node/cli/commands/lint/relationships.js +3 -3
- package/build/src/environment-handlers/node.js +2 -2
- package/build/src/frontend-model-controller.d.ts +9 -8
- package/build/src/frontend-model-controller.d.ts.map +1 -1
- package/build/src/frontend-model-controller.js +26 -19
- package/build/src/frontend-models/base.d.ts +4 -4
- package/build/src/frontend-models/base.d.ts.map +1 -1
- package/build/src/frontend-models/base.js +6 -6
- package/build/src/frontend-models/query.d.ts +7 -7
- package/build/src/frontend-models/query.js +13 -13
- package/build/src/http-server/client/index.d.ts +23 -1
- package/build/src/http-server/client/index.d.ts.map +1 -1
- package/build/src/http-server/client/index.js +55 -17
- package/build/src/http-server/client/response.d.ts +11 -1
- package/build/src/http-server/client/response.d.ts.map +1 -1
- package/build/src/http-server/client/response.js +16 -2
- package/build/src/http-server/client/websocket-session.d.ts +13 -13
- package/build/src/http-server/client/websocket-session.js +14 -14
- package/build/src/http-server/server-client.d.ts +13 -0
- package/build/src/http-server/server-client.d.ts.map +1 -1
- package/build/src/http-server/server-client.js +94 -1
- package/build/src/http-server/websocket-channel.d.ts +12 -11
- package/build/src/http-server/websocket-channel.d.ts.map +1 -1
- package/build/src/http-server/websocket-channel.js +13 -12
- package/build/src/http-server/websocket-connection.d.ts +12 -11
- package/build/src/http-server/websocket-connection.d.ts.map +1 -1
- package/build/src/http-server/websocket-connection.js +13 -12
- package/build/src/http-server/websocket-events-host.d.ts +1 -1
- package/build/src/http-server/websocket-events-host.js +2 -2
- package/build/src/http-server/worker-handler/in-process.d.ts +2 -0
- package/build/src/http-server/worker-handler/in-process.d.ts.map +1 -1
- package/build/src/http-server/worker-handler/in-process.js +42 -11
- package/build/src/http-server/worker-handler/index.d.ts +21 -0
- package/build/src/http-server/worker-handler/index.d.ts.map +1 -1
- package/build/src/http-server/worker-handler/index.js +61 -7
- package/build/src/http-server/worker-handler/worker-thread.d.ts +30 -0
- package/build/src/http-server/worker-handler/worker-thread.d.ts.map +1 -1
- package/build/src/http-server/worker-handler/worker-thread.js +61 -1
- package/build/src/sync/device-identity.d.ts +2 -2
- package/build/src/sync/device-identity.d.ts.map +1 -1
- package/build/src/sync/device-identity.js +4 -4
- package/build/src/sync/local-mutation-log.d.ts +0 -1
- package/build/src/sync/local-mutation-log.d.ts.map +1 -1
- package/build/src/sync/local-mutation-log.js +1 -2
- package/build/src/tenants/tenant-iterator.d.ts +8 -8
- package/build/src/tenants/tenant-iterator.js +9 -9
- package/build/src/tenants/tenant.d.ts +6 -6
- package/build/src/tenants/tenant.js +7 -7
- package/build/sync/device-identity.js +3 -3
- package/build/sync/local-mutation-log.js +0 -1
- package/build/tenants/tenant-iterator.js +8 -8
- package/build/tenants/tenant.js +6 -6
- package/package.json +2 -2
- package/src/background-jobs/cron-expression.js +9 -9
- package/src/background-jobs/forked-runner-child.js +1 -1
- package/src/background-jobs/job-runner.js +21 -15
- package/src/background-jobs/json-socket.js +4 -0
- package/src/background-jobs/main.js +180 -18
- package/src/background-jobs/status-reporter.js +12 -5
- package/src/background-jobs/store.js +132 -50
- package/src/background-jobs/types.js +11 -3
- package/src/background-jobs/worker.js +9 -5
- package/src/beacon/client.js +13 -6
- package/src/configuration.js +31 -29
- package/src/controller.js +9 -3
- package/src/database/drivers/sqlite/base.js +1 -1
- package/src/database/drivers/sqlite/index.js +15 -14
- package/src/database/migrations-ledger.js +16 -16
- package/src/database/query/where-model-class-hash.js +2 -0
- package/src/database/query/with-count.js +1 -1
- package/src/database/record/acts-as-list.js +2 -2
- package/src/database/record/auditing.js +23 -6
- package/src/database/record/index.js +7 -7
- package/src/database/record/validators/uniqueness.js +3 -3
- package/src/database/tenants/data-copier.js +23 -23
- package/src/database/tenants/schema-cloner.js +27 -27
- package/src/environment-handlers/browser.js +0 -1
- package/src/environment-handlers/node/cli/commands/background-jobs-runner.js +2 -1
- package/src/environment-handlers/node/cli/commands/lint/relationships.js +2 -2
- package/src/environment-handlers/node.js +1 -1
- package/src/frontend-model-controller.js +26 -18
- package/src/frontend-models/base.js +5 -5
- package/src/frontend-models/query.js +12 -12
- package/src/http-server/client/index.js +61 -15
- package/src/http-server/client/response.js +17 -1
- package/src/http-server/client/websocket-session.js +13 -13
- package/src/http-server/server-client.js +96 -0
- package/src/http-server/websocket-channel.js +12 -11
- package/src/http-server/websocket-connection.js +12 -11
- package/src/http-server/websocket-events-host.js +1 -1
- package/src/http-server/worker-handler/in-process.js +48 -9
- package/src/http-server/worker-handler/index.js +67 -7
- package/src/http-server/worker-handler/worker-thread.js +68 -0
- package/src/sync/device-identity.js +3 -3
- package/src/sync/local-mutation-log.js +0 -1
- package/src/tenants/tenant-iterator.js +8 -8
- package/src/tenants/tenant.js +6 -6
package/build/configuration.js
CHANGED
|
@@ -2056,7 +2056,8 @@ export default class VelociousConfiguration {
|
|
|
2056
2056
|
|
|
2057
2057
|
/**
|
|
2058
2058
|
* Runs get translator.
|
|
2059
|
-
* @returns {(msgID: string, args?: Record<string, ?>) => string}
|
|
2059
|
+
* @returns {(msgID: string, args?: Record<string, ?>) => string} - The configured translator.
|
|
2060
|
+
*/
|
|
2060
2061
|
getTranslator() {
|
|
2061
2062
|
if (this._translator) return this._translator
|
|
2062
2063
|
|
|
@@ -2156,8 +2157,8 @@ export default class VelociousConfiguration {
|
|
|
2156
2157
|
* Registers a `VelociousWebsocketConnection` subclass under a name.
|
|
2157
2158
|
* Clients that send `{type: "connection-open", connectionType: name}`
|
|
2158
2159
|
* will have this class instantiated for their connection.
|
|
2159
|
-
* @param {string} name
|
|
2160
|
-
* @param {typeof import("./http-server/websocket-connection.js").default} ConnectionClass
|
|
2160
|
+
* @param {string} name - Client-facing connection type name.
|
|
2161
|
+
* @param {typeof import("./http-server/websocket-connection.js").default} ConnectionClass - Websocket connection class.
|
|
2161
2162
|
* @returns {void}
|
|
2162
2163
|
*/
|
|
2163
2164
|
registerWebsocketConnection(name, ConnectionClass) {
|
|
@@ -2168,8 +2169,8 @@ export default class VelociousConfiguration {
|
|
|
2168
2169
|
|
|
2169
2170
|
/**
|
|
2170
2171
|
* Runs get websocket connection class.
|
|
2171
|
-
* @param {string} name
|
|
2172
|
-
* @returns {typeof import("./http-server/websocket-connection.js").default | undefined}
|
|
2172
|
+
* @param {string} name - Connection type name to look up.
|
|
2173
|
+
* @returns {typeof import("./http-server/websocket-connection.js").default | undefined} - Registered websocket connection class.
|
|
2173
2174
|
*/
|
|
2174
2175
|
getWebsocketConnectionClass(name) {
|
|
2175
2176
|
return this._websocketConnectionClasses.get(name)
|
|
@@ -2178,8 +2179,8 @@ export default class VelociousConfiguration {
|
|
|
2178
2179
|
/**
|
|
2179
2180
|
* Registers a `VelociousWebsocketChannel` subclass under a name.
|
|
2180
2181
|
* Clients subscribe via `{type: "channel-subscribe", channelType: name, ...}`.
|
|
2181
|
-
* @param {string} name
|
|
2182
|
-
* @param {typeof import("./http-server/websocket-channel.js").default} ChannelClass
|
|
2182
|
+
* @param {string} name - Client-facing channel type name.
|
|
2183
|
+
* @param {typeof import("./http-server/websocket-channel.js").default} ChannelClass - Websocket channel class.
|
|
2183
2184
|
* @returns {void}
|
|
2184
2185
|
*/
|
|
2185
2186
|
registerWebsocketChannel(name, ChannelClass) {
|
|
@@ -2190,8 +2191,8 @@ export default class VelociousConfiguration {
|
|
|
2190
2191
|
|
|
2191
2192
|
/**
|
|
2192
2193
|
* Runs get websocket channel class.
|
|
2193
|
-
* @param {string} name
|
|
2194
|
-
* @returns {typeof import("./http-server/websocket-channel.js").default | undefined}
|
|
2194
|
+
* @param {string} name - Channel type name to look up.
|
|
2195
|
+
* @returns {typeof import("./http-server/websocket-channel.js").default | undefined} - Registered websocket channel class.
|
|
2195
2196
|
*/
|
|
2196
2197
|
getWebsocketChannelClass(name) {
|
|
2197
2198
|
return this._websocketChannelClasses.get(name)
|
|
@@ -2201,8 +2202,8 @@ export default class VelociousConfiguration {
|
|
|
2201
2202
|
* Tracks a live channel subscription in the global routing registry.
|
|
2202
2203
|
* Called by the session when `canSubscribe()` resolves truthy; the
|
|
2203
2204
|
* session calls `_unregisterWebsocketChannelSubscription` on unsubscribe.
|
|
2204
|
-
* @param {string} name
|
|
2205
|
-
* @param {import("./http-server/websocket-channel.js").default} subscription
|
|
2205
|
+
* @param {string} name - Channel type used as the routing key.
|
|
2206
|
+
* @param {import("./http-server/websocket-channel.js").default} subscription - Live channel subscription to register.
|
|
2206
2207
|
* @returns {void}
|
|
2207
2208
|
*/
|
|
2208
2209
|
_registerWebsocketChannelSubscription(name, subscription) {
|
|
@@ -2218,8 +2219,8 @@ export default class VelociousConfiguration {
|
|
|
2218
2219
|
|
|
2219
2220
|
/**
|
|
2220
2221
|
* Runs unregister websocket channel subscription.
|
|
2221
|
-
* @param {string} name
|
|
2222
|
-
* @param {import("./http-server/websocket-channel.js").default} subscription
|
|
2222
|
+
* @param {string} name - Channel type used as the routing key.
|
|
2223
|
+
* @param {import("./http-server/websocket-channel.js").default} subscription - Live channel subscription to remove.
|
|
2223
2224
|
* @returns {void}
|
|
2224
2225
|
*/
|
|
2225
2226
|
_unregisterWebsocketChannelSubscription(name, subscription) {
|
|
@@ -2262,7 +2263,7 @@ export default class VelociousConfiguration {
|
|
|
2262
2263
|
* connection message / channel dispatch. The wrapper receives the
|
|
2263
2264
|
* session and a `next` callback; it must call `next()` to run the
|
|
2264
2265
|
* handler. Use it to set up AsyncLocalStorage per request.
|
|
2265
|
-
* @param {((session: import("./http-server/client/websocket-session.js").default, next: () => Promise<void>) => Promise<void>) | null} wrapper
|
|
2266
|
+
* @param {((session: import("./http-server/client/websocket-session.js").default, next: () => Promise<void>) => Promise<void>) | null} wrapper - Per-message session-context wrapper, or null to disable it.
|
|
2266
2267
|
* @returns {void}
|
|
2267
2268
|
*/
|
|
2268
2269
|
setWebsocketAroundRequest(wrapper) {
|
|
@@ -2271,7 +2272,7 @@ export default class VelociousConfiguration {
|
|
|
2271
2272
|
|
|
2272
2273
|
/**
|
|
2273
2274
|
* Runs get websocket around request.
|
|
2274
|
-
* @returns {((session: import("./http-server/client/websocket-session.js").default, next: () => Promise<void>) => Promise<void>) | null}
|
|
2275
|
+
* @returns {((session: import("./http-server/client/websocket-session.js").default, next: () => Promise<void>) => Promise<void>) | null} - Websocket session wrapper.
|
|
2275
2276
|
*/
|
|
2276
2277
|
getWebsocketAroundRequest() {
|
|
2277
2278
|
return this._websocketAroundRequest
|
|
@@ -2282,7 +2283,7 @@ export default class VelociousConfiguration {
|
|
|
2282
2283
|
* HTTP and WS-borne. Receives `{request, response, next}` and must
|
|
2283
2284
|
* call `next()` to run the action. Use it for per-request context
|
|
2284
2285
|
* like AsyncLocalStorage-scoped locale or tracing.
|
|
2285
|
-
* @param {((context: {request: import("./http-server/client/request.js").default | import("./http-server/client/websocket-request.js").default, response: import("./http-server/client/response.js").default, next: () => Promise<void>}) => Promise<void>) | null} wrapper
|
|
2286
|
+
* @param {((context: {request: import("./http-server/client/request.js").default | import("./http-server/client/websocket-request.js").default, response: import("./http-server/client/response.js").default, next: () => Promise<void>}) => Promise<void>) | null} wrapper - Per-action request-context wrapper, or null to disable it.
|
|
2286
2287
|
* @returns {void}
|
|
2287
2288
|
*/
|
|
2288
2289
|
setAroundAction(wrapper) {
|
|
@@ -2291,7 +2292,7 @@ export default class VelociousConfiguration {
|
|
|
2291
2292
|
|
|
2292
2293
|
/**
|
|
2293
2294
|
* Runs get around action.
|
|
2294
|
-
* @returns {((context: {request: import("./http-server/client/request.js").default | import("./http-server/client/websocket-request.js").default, response: import("./http-server/client/response.js").default, next: () => Promise<void>}) => Promise<void>) | null}
|
|
2295
|
+
* @returns {((context: {request: import("./http-server/client/request.js").default | import("./http-server/client/websocket-request.js").default, response: import("./http-server/client/response.js").default, next: () => Promise<void>}) => Promise<void>) | null} - HTTP request wrapper.
|
|
2295
2296
|
*/
|
|
2296
2297
|
getAroundAction() {
|
|
2297
2298
|
return this._aroundAction
|
|
@@ -2310,7 +2311,7 @@ export default class VelociousConfiguration {
|
|
|
2310
2311
|
*
|
|
2311
2312
|
* Return `null`/`undefined` to mean "no identity" — resumes still
|
|
2312
2313
|
* succeed if pause and resume both resolve to a nullish value.
|
|
2313
|
-
* @param {((session: import("./http-server/client/websocket-session.js").default) => ? | Promise<?>) | null} resolver
|
|
2314
|
+
* @param {((session: import("./http-server/client/websocket-session.js").default) => ? | Promise<?>) | null} resolver - Authenticated-caller identity resolver, or null to disable identity checks.
|
|
2314
2315
|
* @returns {void}
|
|
2315
2316
|
*/
|
|
2316
2317
|
setWebsocketSessionIdentityResolver(resolver) {
|
|
@@ -2319,14 +2320,15 @@ export default class VelociousConfiguration {
|
|
|
2319
2320
|
|
|
2320
2321
|
/**
|
|
2321
2322
|
* Runs get websocket session identity resolver.
|
|
2322
|
-
* @returns {((session: import("./http-server/client/websocket-session.js").default) => ? | Promise<?>) | null}
|
|
2323
|
+
* @returns {((session: import("./http-server/client/websocket-session.js").default) => ? | Promise<?>) | null} - The configured identity resolver.
|
|
2324
|
+
*/
|
|
2323
2325
|
getWebsocketSessionIdentityResolver() {
|
|
2324
2326
|
return this._websocketSessionIdentityResolver
|
|
2325
2327
|
}
|
|
2326
2328
|
|
|
2327
2329
|
/**
|
|
2328
2330
|
* Runs set websocket session grace seconds.
|
|
2329
|
-
* @param {number} seconds
|
|
2331
|
+
* @param {number} seconds - Grace period before a paused session expires.
|
|
2330
2332
|
* @returns {void}
|
|
2331
2333
|
*/
|
|
2332
2334
|
setWebsocketSessionGraceSeconds(seconds) {
|
|
@@ -2336,7 +2338,7 @@ export default class VelociousConfiguration {
|
|
|
2336
2338
|
|
|
2337
2339
|
/**
|
|
2338
2340
|
* Runs set websocket session heartbeat seconds.
|
|
2339
|
-
* @param {number} seconds
|
|
2341
|
+
* @param {number} seconds - Heartbeat interval, with zero disabling reaping.
|
|
2340
2342
|
* @returns {void}
|
|
2341
2343
|
*/
|
|
2342
2344
|
setWebsocketSessionHeartbeatSeconds(seconds) {
|
|
@@ -2349,7 +2351,7 @@ export default class VelociousConfiguration {
|
|
|
2349
2351
|
* timer. When the timer fires, the session's permanent teardown
|
|
2350
2352
|
* hook is invoked. Called by the session itself from `_handleClose`
|
|
2351
2353
|
* when there is resumable state (live Connections / Channel subs).
|
|
2352
|
-
* @param {import("./http-server/client/websocket-session.js").default} session
|
|
2354
|
+
* @param {import("./http-server/client/websocket-session.js").default} session - Resumable session to retain during its grace period.
|
|
2353
2355
|
* @returns {void}
|
|
2354
2356
|
*/
|
|
2355
2357
|
_pauseWebsocketSession(session) {
|
|
@@ -2372,8 +2374,8 @@ export default class VelociousConfiguration {
|
|
|
2372
2374
|
/**
|
|
2373
2375
|
* Looks up a paused session by id (does NOT remove it — caller is
|
|
2374
2376
|
* expected to call `_resumeWebsocketSession` to complete the handoff).
|
|
2375
|
-
* @param {string} sessionId
|
|
2376
|
-
* @returns {import("./http-server/client/websocket-session.js").default | null}
|
|
2377
|
+
* @param {string} sessionId - Paused session identifier to look up.
|
|
2378
|
+
* @returns {import("./http-server/client/websocket-session.js").default | null} - Paused session with the requested identifier, if present.
|
|
2377
2379
|
*/
|
|
2378
2380
|
_findPausedWebsocketSession(sessionId) {
|
|
2379
2381
|
return this._pausedWebsocketSessions.get(sessionId)?.session || null
|
|
@@ -2383,7 +2385,7 @@ export default class VelociousConfiguration {
|
|
|
2383
2385
|
* Removes a paused session from the registry and cancels its grace
|
|
2384
2386
|
* timer. Called on successful resume handoff and on explicit
|
|
2385
2387
|
* expiry.
|
|
2386
|
-
* @param {string} sessionId
|
|
2388
|
+
* @param {string} sessionId - Paused session identifier to remove and cancel.
|
|
2387
2389
|
* @returns {void}
|
|
2388
2390
|
*/
|
|
2389
2391
|
_clearPausedWebsocketSession(sessionId) {
|
|
@@ -2398,7 +2400,7 @@ export default class VelociousConfiguration {
|
|
|
2398
2400
|
/**
|
|
2399
2401
|
* Grace-timer callback. Calls the session's permanent-teardown
|
|
2400
2402
|
* hook and drops it from the registry.
|
|
2401
|
-
* @param {string} sessionId
|
|
2403
|
+
* @param {string} sessionId - Paused session identifier whose grace period expired.
|
|
2402
2404
|
* @returns {void}
|
|
2403
2405
|
*/
|
|
2404
2406
|
_expireWebsocketSession(sessionId) {
|
|
@@ -2416,9 +2418,9 @@ export default class VelociousConfiguration {
|
|
|
2416
2418
|
|
|
2417
2419
|
/**
|
|
2418
2420
|
* Runs broadcast to channel.
|
|
2419
|
-
* @param {string} name
|
|
2420
|
-
* @param {Record<string, ?>} broadcastParams
|
|
2421
|
-
* @param {?} body
|
|
2421
|
+
* @param {string} name - Channel type receiving the broadcast.
|
|
2422
|
+
* @param {Record<string, ?>} broadcastParams - Values used to match eligible subscriptions.
|
|
2423
|
+
* @param {?} body - Broadcast payload delivered to matching subscriptions.
|
|
2422
2424
|
* @returns {void}
|
|
2423
2425
|
*/
|
|
2424
2426
|
broadcastToChannel(name, broadcastParams, body) {
|
package/build/controller.js
CHANGED
|
@@ -169,7 +169,7 @@ export default class VelociousController {
|
|
|
169
169
|
const beforeActions = currentControllerClass._beforeActions
|
|
170
170
|
|
|
171
171
|
if (beforeActions) {
|
|
172
|
-
const controllerPrototype = /** @type {Record<string,
|
|
172
|
+
const controllerPrototype = /** @type {Record<string, ((...args: Array<?>) => ?) | undefined>} */ (/** @type {?} */ (currentControllerClass.prototype))
|
|
173
173
|
|
|
174
174
|
for (const beforeActionName of beforeActions) {
|
|
175
175
|
const beforeAction = controllerPrototype[beforeActionName]
|
|
@@ -266,6 +266,7 @@ export default class VelociousController {
|
|
|
266
266
|
/**
|
|
267
267
|
* Runs render json arg.
|
|
268
268
|
* @param {object} json - JSON payload.
|
|
269
|
+
* @returns {void} - Sets the response JSON payload.
|
|
269
270
|
*/
|
|
270
271
|
renderJsonArg(json) {
|
|
271
272
|
return this._measureViewRender(() => {
|
|
@@ -339,11 +340,12 @@ export default class VelociousController {
|
|
|
339
340
|
* @param {object} [args] - Options object.
|
|
340
341
|
* @param {string} [args.contentType] - Content type.
|
|
341
342
|
* @param {number | string} [args.status] - Status.
|
|
343
|
+
* @param {(result: "completed" | "aborted") => void | Promise<void>} [args.onFinished] - Called once after file delivery completes or aborts.
|
|
342
344
|
* @returns {void} - No return value.
|
|
343
345
|
*/
|
|
344
346
|
sendFile(filePath, args = {}) {
|
|
345
347
|
this._measureViewRender(() => {
|
|
346
|
-
const {contentType, status, ...restArgs} = args
|
|
348
|
+
const {contentType, onFinished, status, ...restArgs} = args
|
|
347
349
|
|
|
348
350
|
restArgsError(restArgs)
|
|
349
351
|
|
|
@@ -351,6 +353,10 @@ export default class VelociousController {
|
|
|
351
353
|
throw new Error(`Expected file path to be a non-empty string, got: ${String(filePath)}`)
|
|
352
354
|
}
|
|
353
355
|
|
|
356
|
+
if (onFinished !== undefined && typeof onFinished !== "function") {
|
|
357
|
+
throw new Error(`Expected onFinished to be a function, got: ${typeof onFinished}`)
|
|
358
|
+
}
|
|
359
|
+
|
|
354
360
|
const detectedContentType = contentType || this.sendFileContentType(filePath)
|
|
355
361
|
|
|
356
362
|
if (detectedContentType) {
|
|
@@ -361,7 +367,7 @@ export default class VelociousController {
|
|
|
361
367
|
this._response.setStatus(status)
|
|
362
368
|
}
|
|
363
369
|
|
|
364
|
-
this._response.setFilePath(filePath)
|
|
370
|
+
this._response.setFilePath(filePath, onFinished || null)
|
|
365
371
|
})
|
|
366
372
|
}
|
|
367
373
|
|
|
@@ -401,7 +401,7 @@ export default class VelociousDatabaseDriversSqliteBase extends Base {
|
|
|
401
401
|
const waiters = state.waitersByName.get(name) || []
|
|
402
402
|
/**
|
|
403
403
|
* Timeout handle.
|
|
404
|
-
* @type {
|
|
404
|
+
* @type {ReturnType<typeof setTimeout> | null} */
|
|
405
405
|
let timeoutHandle = null
|
|
406
406
|
/**
|
|
407
407
|
* Remove and resolve.
|
|
@@ -93,7 +93,7 @@ export default class VelociousDatabaseDriversSqliteNode extends Base {
|
|
|
93
93
|
* (create and remove) per critical section.
|
|
94
94
|
* @param {string} name - Lock name.
|
|
95
95
|
* @param {{timeoutMs?: number | null}} [args] - Optional timeout in milliseconds; `null`, `undefined`, or negative blocks forever.
|
|
96
|
-
* @returns {Promise<boolean>}
|
|
96
|
+
* @returns {Promise<boolean>} - Whether the advisory lock was acquired.
|
|
97
97
|
*/
|
|
98
98
|
async acquireAdvisoryLock(name, {timeoutMs} = {}) {
|
|
99
99
|
const deadline = typeof timeoutMs === "number" && timeoutMs >= 0 ? Date.now() + timeoutMs : null
|
|
@@ -121,7 +121,7 @@ export default class VelociousDatabaseDriversSqliteNode extends Base {
|
|
|
121
121
|
/**
|
|
122
122
|
* Runs try acquire advisory lock.
|
|
123
123
|
* @param {string} name - Lock name.
|
|
124
|
-
* @returns {Promise<boolean>}
|
|
124
|
+
* @returns {Promise<boolean>} - Whether the advisory lock was acquired immediately.
|
|
125
125
|
*/
|
|
126
126
|
async tryAcquireAdvisoryLock(name) {
|
|
127
127
|
const inProcessAcquired = await super.tryAcquireAdvisoryLock(name)
|
|
@@ -151,7 +151,7 @@ export default class VelociousDatabaseDriversSqliteNode extends Base {
|
|
|
151
151
|
* and the filesystem state is left alone so we never delete somebody
|
|
152
152
|
* else's lock directory.
|
|
153
153
|
* @param {string} name - Lock name.
|
|
154
|
-
* @returns {Promise<boolean>}
|
|
154
|
+
* @returns {Promise<boolean>} - Whether the advisory lock was released.
|
|
155
155
|
*/
|
|
156
156
|
async releaseAdvisoryLock(name) {
|
|
157
157
|
const inProcessReleased = await super.releaseAdvisoryLock(name)
|
|
@@ -166,7 +166,7 @@ export default class VelociousDatabaseDriversSqliteNode extends Base {
|
|
|
166
166
|
/**
|
|
167
167
|
* Runs is advisory lock held.
|
|
168
168
|
* @param {string} name - Lock name.
|
|
169
|
-
* @returns {Promise<boolean>}
|
|
169
|
+
* @returns {Promise<boolean>} - Whether the advisory lock is held.
|
|
170
170
|
*/
|
|
171
171
|
async isAdvisoryLockHeld(name) {
|
|
172
172
|
if (await super.isAdvisoryLockHeld(name)) return true
|
|
@@ -176,7 +176,8 @@ export default class VelociousDatabaseDriversSqliteNode extends Base {
|
|
|
176
176
|
|
|
177
177
|
/**
|
|
178
178
|
* Runs resolve advisory lock directory.
|
|
179
|
-
* @returns {string}
|
|
179
|
+
* @returns {string} - The advisory-lock directory.
|
|
180
|
+
*/
|
|
180
181
|
_resolveAdvisoryLockDirectory() {
|
|
181
182
|
if (!this._advisoryLockDirectory) {
|
|
182
183
|
// Fall back to deriving the directory for callers that invoked
|
|
@@ -192,7 +193,7 @@ export default class VelociousDatabaseDriversSqliteNode extends Base {
|
|
|
192
193
|
/**
|
|
193
194
|
* Runs advisory lock path.
|
|
194
195
|
* @param {string} name - Lock name.
|
|
195
|
-
* @returns {string}
|
|
196
|
+
* @returns {string} - Filesystem path for the advisory lock.
|
|
196
197
|
*/
|
|
197
198
|
_advisoryLockPath(name) {
|
|
198
199
|
const hash = createHash("sha256").update(name).digest("hex").slice(0, 16)
|
|
@@ -228,7 +229,7 @@ export default class VelociousDatabaseDriversSqliteNode extends Base {
|
|
|
228
229
|
* Runs acquire advisory lock file.
|
|
229
230
|
* @param {string} name - Lock name.
|
|
230
231
|
* @param {{timeoutMs?: number | null}} args - Timeout args.
|
|
231
|
-
* @returns {Promise<boolean>}
|
|
232
|
+
* @returns {Promise<boolean>} - Whether the advisory-lock file was acquired.
|
|
232
233
|
*/
|
|
233
234
|
async _acquireAdvisoryLockFile(name, {timeoutMs}) {
|
|
234
235
|
await this._ensureAdvisoryLockDirectory()
|
|
@@ -247,7 +248,7 @@ export default class VelociousDatabaseDriversSqliteNode extends Base {
|
|
|
247
248
|
|
|
248
249
|
return true
|
|
249
250
|
} catch (error) {
|
|
250
|
-
if (/** @type {
|
|
251
|
+
if (/** @type {Error & {code?: string}} */ (error)?.code !== "EEXIST") throw error
|
|
251
252
|
|
|
252
253
|
if (await this._isAdvisoryLockStale(lockPath)) {
|
|
253
254
|
await fs.rm(lockPath, {recursive: true, force: true})
|
|
@@ -270,7 +271,7 @@ export default class VelociousDatabaseDriversSqliteNode extends Base {
|
|
|
270
271
|
/**
|
|
271
272
|
* Runs try acquire advisory lock file.
|
|
272
273
|
* @param {string} name - Lock name.
|
|
273
|
-
* @returns {Promise<boolean>}
|
|
274
|
+
* @returns {Promise<boolean>} - Whether the advisory-lock file was acquired immediately.
|
|
274
275
|
*/
|
|
275
276
|
async _tryAcquireAdvisoryLockFile(name) {
|
|
276
277
|
await this._ensureAdvisoryLockDirectory()
|
|
@@ -283,7 +284,7 @@ export default class VelociousDatabaseDriversSqliteNode extends Base {
|
|
|
283
284
|
|
|
284
285
|
return true
|
|
285
286
|
} catch (error) {
|
|
286
|
-
if (/** @type {
|
|
287
|
+
if (/** @type {Error & {code?: string}} */ (error)?.code !== "EEXIST") throw error
|
|
287
288
|
|
|
288
289
|
if (await this._isAdvisoryLockStale(lockPath)) {
|
|
289
290
|
await fs.rm(lockPath, {recursive: true, force: true})
|
|
@@ -294,7 +295,7 @@ export default class VelociousDatabaseDriversSqliteNode extends Base {
|
|
|
294
295
|
|
|
295
296
|
return true
|
|
296
297
|
} catch (retryError) {
|
|
297
|
-
if (/** @type {
|
|
298
|
+
if (/** @type {Error & {code?: string}} */ (retryError)?.code === "EEXIST") return false
|
|
298
299
|
|
|
299
300
|
throw retryError
|
|
300
301
|
}
|
|
@@ -324,7 +325,7 @@ export default class VelociousDatabaseDriversSqliteNode extends Base {
|
|
|
324
325
|
/**
|
|
325
326
|
* Runs is advisory lock file held.
|
|
326
327
|
* @param {string} name - Lock name.
|
|
327
|
-
* @returns {Promise<boolean>}
|
|
328
|
+
* @returns {Promise<boolean>} - Whether the advisory-lock file exists and is active.
|
|
328
329
|
*/
|
|
329
330
|
async _isAdvisoryLockFileHeld(name) {
|
|
330
331
|
const lockPath = this._advisoryLockPath(name)
|
|
@@ -345,7 +346,7 @@ export default class VelociousDatabaseDriversSqliteNode extends Base {
|
|
|
345
346
|
* probe a PID on another machine; operators in that situation should
|
|
346
347
|
* remove stale lock directories by hand if they linger.
|
|
347
348
|
* @param {string} lockPath - Absolute path of the lock directory.
|
|
348
|
-
* @returns {Promise<boolean>}
|
|
349
|
+
* @returns {Promise<boolean>} - Whether the advisory-lock file is stale.
|
|
349
350
|
*/
|
|
350
351
|
async _isAdvisoryLockStale(lockPath) {
|
|
351
352
|
/**
|
|
@@ -382,7 +383,7 @@ export default class VelociousDatabaseDriversSqliteNode extends Base {
|
|
|
382
383
|
|
|
383
384
|
return false
|
|
384
385
|
} catch (error) {
|
|
385
|
-
return /** @type {
|
|
386
|
+
return /** @type {Error & {code?: string}} */ (error)?.code === "ESRCH"
|
|
386
387
|
}
|
|
387
388
|
}
|
|
388
389
|
}
|
|
@@ -18,7 +18,7 @@ const TABLE_NAME = "schema_migrations"
|
|
|
18
18
|
export default class MigrationsLedger {
|
|
19
19
|
/**
|
|
20
20
|
* The ledger table name.
|
|
21
|
-
* @returns {string}
|
|
21
|
+
* @returns {string} - Ledger table name.
|
|
22
22
|
*/
|
|
23
23
|
static tableName() {
|
|
24
24
|
return TABLE_NAME
|
|
@@ -26,8 +26,8 @@ export default class MigrationsLedger {
|
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Whether the ledger table exists on the given database.
|
|
29
|
-
* @param {import("./drivers/base.js").default} db
|
|
30
|
-
* @returns {Promise<boolean>}
|
|
29
|
+
* @param {import("./drivers/base.js").default} db - Database whose migration ledger is inspected.
|
|
30
|
+
* @returns {Promise<boolean>} - Whether the ledger table exists.
|
|
31
31
|
*/
|
|
32
32
|
static async tableExists(db) {
|
|
33
33
|
const table = await db.getTableByName(TABLE_NAME, {throwError: false})
|
|
@@ -38,7 +38,7 @@ export default class MigrationsLedger {
|
|
|
38
38
|
/**
|
|
39
39
|
* Creates the ledger table if it does not exist. This is the single definition of
|
|
40
40
|
* the `schema_migrations` table shape.
|
|
41
|
-
* @param {import("./drivers/base.js").default} db
|
|
41
|
+
* @param {import("./drivers/base.js").default} db - Database that should contain the ledger table.
|
|
42
42
|
* @returns {Promise<void>}
|
|
43
43
|
*/
|
|
44
44
|
static async ensureTable(db) {
|
|
@@ -57,8 +57,8 @@ export default class MigrationsLedger {
|
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
59
|
* Every applied migration version recorded in the ledger.
|
|
60
|
-
* @param {import("./drivers/base.js").default} db
|
|
61
|
-
* @returns {Promise<string[]>}
|
|
60
|
+
* @param {import("./drivers/base.js").default} db - Database whose applied versions are loaded.
|
|
61
|
+
* @returns {Promise<string[]>} - Applied migration versions.
|
|
62
62
|
*/
|
|
63
63
|
static async appliedVersions(db) {
|
|
64
64
|
const rows = await db.select(TABLE_NAME)
|
|
@@ -68,9 +68,9 @@ export default class MigrationsLedger {
|
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
70
|
* Whether the given version is recorded as applied.
|
|
71
|
-
* @param {import("./drivers/base.js").default} db
|
|
72
|
-
* @param {string} version
|
|
73
|
-
* @returns {Promise<boolean>}
|
|
71
|
+
* @param {import("./drivers/base.js").default} db - Database whose ledger is queried.
|
|
72
|
+
* @param {string} version - Migration version to look up.
|
|
73
|
+
* @returns {Promise<boolean>} - Whether the migration version is applied.
|
|
74
74
|
*/
|
|
75
75
|
static async hasVersion(db, version) {
|
|
76
76
|
const rows = await db.newQuery()
|
|
@@ -84,8 +84,8 @@ export default class MigrationsLedger {
|
|
|
84
84
|
/**
|
|
85
85
|
* Records a single version as applied. The targeted existence check keeps the
|
|
86
86
|
* migrator's per-migration hot path cheap (no full-table load per migration).
|
|
87
|
-
* @param {import("./drivers/base.js").default} db
|
|
88
|
-
* @param {string} version
|
|
87
|
+
* @param {import("./drivers/base.js").default} db - Database whose ledger receives the version.
|
|
88
|
+
* @param {string} version - Migration version to record as applied.
|
|
89
89
|
* @returns {Promise<void>}
|
|
90
90
|
*/
|
|
91
91
|
static async recordVersion(db, version) {
|
|
@@ -96,8 +96,8 @@ export default class MigrationsLedger {
|
|
|
96
96
|
|
|
97
97
|
/**
|
|
98
98
|
* Removes a version from the ledger (used when migrating down).
|
|
99
|
-
* @param {import("./drivers/base.js").default} db
|
|
100
|
-
* @param {string} version
|
|
99
|
+
* @param {import("./drivers/base.js").default} db - Database whose ledger loses the version.
|
|
100
|
+
* @param {string} version - Migration version to mark as unapplied.
|
|
101
101
|
* @returns {Promise<void>}
|
|
102
102
|
*/
|
|
103
103
|
static async removeVersion(db, version) {
|
|
@@ -108,8 +108,8 @@ export default class MigrationsLedger {
|
|
|
108
108
|
* Baselines a database's ledger: records each version as applied without running
|
|
109
109
|
* its migration. Idempotent — already-recorded versions are skipped. Ensures the
|
|
110
110
|
* ledger table exists first, then loads the existing set once for the whole batch.
|
|
111
|
-
* @param {import("./drivers/base.js").default} db
|
|
112
|
-
* @param {string[]} versions
|
|
111
|
+
* @param {import("./drivers/base.js").default} db - Database whose ledger should be baselined.
|
|
112
|
+
* @param {string[]} versions - Migration versions to record without running them.
|
|
113
113
|
* @returns {Promise<string[]>} The versions that were newly recorded.
|
|
114
114
|
*/
|
|
115
115
|
static async markApplied(db, versions) {
|
|
@@ -136,7 +136,7 @@ export default class MigrationsLedger {
|
|
|
136
136
|
* provisioning path advanced `targetDb`'s schema to match `sourceDb` out of band
|
|
137
137
|
* (e.g. cloning table structure between databases): the migrations are, by
|
|
138
138
|
* construction, already applied on the target, so record them without re-running.
|
|
139
|
-
* @param {{sourceDb: import("./drivers/base.js").default, targetDb: import("./drivers/base.js").default}} args
|
|
139
|
+
* @param {{sourceDb: import("./drivers/base.js").default, targetDb: import("./drivers/base.js").default}} args - Source ledger and target database to baseline.
|
|
140
140
|
* @returns {Promise<string[]>} The versions that were newly recorded on the target.
|
|
141
141
|
*/
|
|
142
142
|
static async baselineFromDatabase({sourceDb, targetDb}) {
|
|
@@ -316,6 +316,7 @@ export default class VelociousDatabaseQueryWhereModelClassHash extends WhereBase
|
|
|
316
316
|
/**
|
|
317
317
|
* Normalize.
|
|
318
318
|
* @param {?} entry - Value to normalize.
|
|
319
|
+
* @returns {?} - SQLite predicate value with booleans encoded as 1 or 0.
|
|
319
320
|
*/
|
|
320
321
|
const normalize = (entry) => {
|
|
321
322
|
if (entry === true) return 1
|
|
@@ -353,6 +354,7 @@ export default class VelociousDatabaseQueryWhereModelClassHash extends WhereBase
|
|
|
353
354
|
/**
|
|
354
355
|
* Normalize.
|
|
355
356
|
* @param {?} entry - Value to normalize.
|
|
357
|
+
* @returns {?} - Column-compatible predicate value, or the no-match sentinel for numeric UUIDs.
|
|
356
358
|
*/
|
|
357
359
|
const normalize = (entry) => {
|
|
358
360
|
if (isUuidType && typeof entry === "number") return NO_MATCH
|
|
@@ -85,7 +85,7 @@ export function normalizeWithCount(spec) {
|
|
|
85
85
|
/**
|
|
86
86
|
* Runs entry from name.
|
|
87
87
|
* @param {string} name - Relationship name (attribute name is derived by appending "Count").
|
|
88
|
-
* @returns {WithCountEntry}
|
|
88
|
+
* @returns {WithCountEntry} - Normalized association-count entry.
|
|
89
89
|
*/
|
|
90
90
|
function entryFromName(name) {
|
|
91
91
|
return {
|
|
@@ -21,7 +21,7 @@ function setShiftingFlag(record, value) {
|
|
|
21
21
|
/**
|
|
22
22
|
* Runs is shifting.
|
|
23
23
|
* @param {import("./index.js").default} record - Model instance.
|
|
24
|
-
* @returns {boolean}
|
|
24
|
+
* @returns {boolean} - Whether list positions are currently shifting.
|
|
25
25
|
*/
|
|
26
26
|
function isShifting(record) {
|
|
27
27
|
// @ts-ignore - Symbol indexing on Record instances
|
|
@@ -341,7 +341,7 @@ async function highestPositionInScope({record, positionColumn, scope, scopeValue
|
|
|
341
341
|
* _belongsToChanges.
|
|
342
342
|
* @param {import("./index.js").default} record - Model instance.
|
|
343
343
|
* @param {string} scope - camelCase scope attribute name (e.g. "projectId").
|
|
344
|
-
* @returns {string | number | null}
|
|
344
|
+
* @returns {string | number | null} - Current list position value.
|
|
345
345
|
*/
|
|
346
346
|
function resolveScopeValue(record, scope) {
|
|
347
347
|
const attrValue = record.readAttribute(scope)
|
|
@@ -74,7 +74,12 @@ let globalEventConnections = {}
|
|
|
74
74
|
|
|
75
75
|
/** @type {AuditEventsType} */
|
|
76
76
|
const AuditEvents = {
|
|
77
|
-
/**
|
|
77
|
+
/**
|
|
78
|
+
* Fire all registered callbacks for a model type and action.
|
|
79
|
+
* @param {string} type - Audited model type whose listeners should fire.
|
|
80
|
+
* @param {string} action - Audit action whose listeners should fire.
|
|
81
|
+
* @param {AuditEventPayload} args - Audit event delivered to matching listeners.
|
|
82
|
+
*/
|
|
78
83
|
call(type, action, args) {
|
|
79
84
|
const actions = globalEventConnections[type] || {}
|
|
80
85
|
const callbacks = actions[action] || []
|
|
@@ -84,7 +89,13 @@ const AuditEvents = {
|
|
|
84
89
|
}
|
|
85
90
|
},
|
|
86
91
|
|
|
87
|
-
/**
|
|
92
|
+
/**
|
|
93
|
+
* Register a callback for a model type and action.
|
|
94
|
+
* @param {string} type - Audited model type to observe.
|
|
95
|
+
* @param {string} action - Audit action to observe.
|
|
96
|
+
* @param {(args: AuditEventPayload) => void} callback - Listener invoked for matching audit events.
|
|
97
|
+
* @returns {() => void} - Callback that removes the registration.
|
|
98
|
+
*/
|
|
88
99
|
connect(type, action, callback) {
|
|
89
100
|
if (!globalEventConnections[type]) {
|
|
90
101
|
globalEventConnections[type] = {}
|
|
@@ -109,7 +120,7 @@ const AuditEvents = {
|
|
|
109
120
|
}
|
|
110
121
|
},
|
|
111
122
|
|
|
112
|
-
/** Clear all registered callbacks.
|
|
123
|
+
/** Clear all registered callbacks. */
|
|
113
124
|
reset() {
|
|
114
125
|
globalEventConnections = {}
|
|
115
126
|
}
|
|
@@ -244,7 +255,10 @@ function sharedAuditClass(modelClass) {
|
|
|
244
255
|
* Framework-owned Audit model for the shared `audits` table.
|
|
245
256
|
*/
|
|
246
257
|
class Audit extends dbRecordClass {
|
|
247
|
-
/**
|
|
258
|
+
/**
|
|
259
|
+
* Returns the backing table name.
|
|
260
|
+
* @returns {string} - Shared `audits` table name.
|
|
261
|
+
*/
|
|
248
262
|
static tableName() {
|
|
249
263
|
return "audits"
|
|
250
264
|
}
|
|
@@ -291,7 +305,10 @@ function dedicatedAuditClass(modelClass, tableName) {
|
|
|
291
305
|
* Framework-owned per-model Audit class.
|
|
292
306
|
*/
|
|
293
307
|
class ModelAudit extends dbRecordClass {
|
|
294
|
-
/**
|
|
308
|
+
/**
|
|
309
|
+
* Returns the backing table name.
|
|
310
|
+
* @returns {string} - Dedicated audit table supplied for this model class.
|
|
311
|
+
*/
|
|
295
312
|
static tableName() {
|
|
296
313
|
return tableName
|
|
297
314
|
}
|
|
@@ -906,7 +923,7 @@ function normalizeAction(action) {
|
|
|
906
923
|
* Creates the shared audit tables migration up/down callbacks for use inside
|
|
907
924
|
* a Migration class. The `table` parameter is a Migration instance.
|
|
908
925
|
* @param {{id?: {type: string}}} [options] - ID column options.
|
|
909
|
-
* @returns {{down: (table: import("../migration/index.js").default) => Promise<void>, up: (table: import("../migration/index.js").default) => Promise<void>}}
|
|
926
|
+
* @returns {{down: (table: import("../migration/index.js").default) => Promise<void>, up: (table: import("../migration/index.js").default) => Promise<void>}} - Up/down callbacks for the shared audit tables.
|
|
910
927
|
*/
|
|
911
928
|
function createSharedAuditTablesMigration(options = {}) {
|
|
912
929
|
const opts = /** @type {{id?: {type: string}}} */ (options)
|
|
@@ -2688,7 +2688,7 @@ class VelociousDatabaseRecord {
|
|
|
2688
2688
|
* @param {string} name - Lock name (for the error message).
|
|
2689
2689
|
* @param {() => Promise<T>} callback - Callback holding the lock.
|
|
2690
2690
|
* @param {number | null} [holdTimeoutMs] - Max hold time; falsy disables the timeout.
|
|
2691
|
-
* @returns {Promise<T>}
|
|
2691
|
+
* @returns {Promise<T>} - Callback result after the lock-protected operation.
|
|
2692
2692
|
*/
|
|
2693
2693
|
static async runWithAdvisoryLockHoldTimeout(name, callback, holdTimeoutMs) {
|
|
2694
2694
|
return await AdvisoryLockRunner.runWithAdvisoryLockHoldTimeout(name, callback, holdTimeoutMs)
|
|
@@ -3816,7 +3816,7 @@ class VelociousDatabaseRecord {
|
|
|
3816
3816
|
* column of the same name. Returns the attached number, or 0 when
|
|
3817
3817
|
* `.withCount(...)` wasn't requested for this attribute.
|
|
3818
3818
|
* @param {string} attributeName - Attribute name, e.g. `"tasksCount"` or a custom `"activeMembersCount"` from `.withCount({activeMembersCount: {...}})`.
|
|
3819
|
-
* @returns {number}
|
|
3819
|
+
* @returns {number} - Attached association count, or zero when absent.
|
|
3820
3820
|
*/
|
|
3821
3821
|
readCount(attributeName) {
|
|
3822
3822
|
return readPayloadAssociationCount(/** @type {import("../../record-payload-values.js").RecordPayloadValuesTarget} */ (/** @type {?} */ (this)), attributeName)
|
|
@@ -3837,7 +3837,7 @@ class VelociousDatabaseRecord {
|
|
|
3837
3837
|
* All attached association counts as a plain object. Used by the
|
|
3838
3838
|
* frontend-model serializer to ship counts alongside the record
|
|
3839
3839
|
* attributes on the wire.
|
|
3840
|
-
* @returns {Record<string, number>}
|
|
3840
|
+
* @returns {Record<string, number>} - Association counts keyed by attribute name.
|
|
3841
3841
|
*/
|
|
3842
3842
|
associationCounts() {
|
|
3843
3843
|
/**
|
|
@@ -3864,7 +3864,7 @@ class VelociousDatabaseRecord {
|
|
|
3864
3864
|
* registered fn for this record (e.g. no child rows matched the
|
|
3865
3865
|
* aggregate).
|
|
3866
3866
|
* @param {string} name - queryData attribute name (matches a SELECT alias from the registered fn).
|
|
3867
|
-
* @returns {?}
|
|
3867
|
+
* @returns {?} - Attached query-data value.
|
|
3868
3868
|
*/
|
|
3869
3869
|
queryData(name) {
|
|
3870
3870
|
return readPayloadQueryData(/** @type {import("../../record-payload-values.js").RecordPayloadValuesTarget} */ (/** @type {?} */ (this)), name)
|
|
@@ -3886,7 +3886,7 @@ class VelociousDatabaseRecord {
|
|
|
3886
3886
|
* All attached queryData values as a plain object. Used by the
|
|
3887
3887
|
* frontend-model serializer to ship queryData alongside the record
|
|
3888
3888
|
* attributes on the wire.
|
|
3889
|
-
* @returns {Record<string, ?>}
|
|
3889
|
+
* @returns {Record<string, ?>} - Query-data values keyed by name.
|
|
3890
3890
|
*/
|
|
3891
3891
|
queryDataValues() {
|
|
3892
3892
|
/**
|
|
@@ -3914,7 +3914,7 @@ class VelociousDatabaseRecord {
|
|
|
3914
3914
|
* `record.can("update")` without first checking whether the ability
|
|
3915
3915
|
* was loaded.
|
|
3916
3916
|
* @param {string} action - Ability action name, e.g. `"update"`.
|
|
3917
|
-
* @returns {boolean}
|
|
3917
|
+
* @returns {boolean} - Whether the requested ability is allowed.
|
|
3918
3918
|
*/
|
|
3919
3919
|
can(action) {
|
|
3920
3920
|
return readPayloadComputedAbility(/** @type {import("../../record-payload-values.js").RecordPayloadValuesTarget} */ (/** @type {?} */ (this)), action)
|
|
@@ -3936,7 +3936,7 @@ class VelociousDatabaseRecord {
|
|
|
3936
3936
|
* All attached per-record ability results as a plain object. Used
|
|
3937
3937
|
* by the frontend-model serializer to ship results alongside the
|
|
3938
3938
|
* record attributes on the wire.
|
|
3939
|
-
* @returns {Record<string, boolean>}
|
|
3939
|
+
* @returns {Record<string, boolean>} - Ability results keyed by action.
|
|
3940
3940
|
*/
|
|
3941
3941
|
computedAbilities() {
|
|
3942
3942
|
/**
|