velocious 1.0.526 → 1.0.528
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 +12 -0
- package/build/background-jobs/main.js +16 -1
- package/build/background-jobs/store.js +16 -1
- package/build/background-jobs/types.js +1 -0
- package/build/src/background-jobs/main.d.ts.map +1 -1
- package/build/src/background-jobs/main.js +15 -2
- package/build/src/background-jobs/store.d.ts +7 -0
- package/build/src/background-jobs/store.d.ts.map +1 -1
- package/build/src/background-jobs/store.js +17 -2
- package/build/src/background-jobs/types.d.ts +5 -0
- package/build/src/background-jobs/types.d.ts.map +1 -1
- package/build/src/background-jobs/types.js +2 -1
- package/package.json +1 -1
- package/src/background-jobs/main.js +16 -1
- package/src/background-jobs/store.js +16 -1
- package/src/background-jobs/types.js +1 -0
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* @property {string} [concurrencyKey] - Opaque non-empty key used to share a concurrency cap. Overrides any queue-derived cap.
|
|
16
16
|
* @property {number} [maxConcurrency] - Positive integer cap; must be paired with `concurrencyKey`.
|
|
17
17
|
* @property {boolean} [deduplicateWhileQueued] - When true (requires `concurrencyKey`), skip the enqueue if a still-queued job with the same `concurrencyKey` already exists, returning that job's id. Keeps an interval-scheduled recurring job (e.g. retention pruning) from piling up redundant queued rows when it runs slower than its interval or no worker is free.
|
|
18
|
+
* @property {number} [scheduledAtMs] - Epoch timestamp in milliseconds when the job becomes eligible for dispatch. Defaults to enqueue time.
|
|
18
19
|
*/
|
|
19
20
|
/**
|
|
20
21
|
* @typedef {object} BackgroundJobPayload
|
|
@@ -121,6 +122,10 @@ export type BackgroundJobOptions = {
|
|
|
121
122
|
* - When true (requires `concurrencyKey`), skip the enqueue if a still-queued job with the same `concurrencyKey` already exists, returning that job's id. Keeps an interval-scheduled recurring job (e.g. retention pruning) from piling up redundant queued rows when it runs slower than its interval or no worker is free.
|
|
122
123
|
*/
|
|
123
124
|
deduplicateWhileQueued?: boolean | undefined;
|
|
125
|
+
/**
|
|
126
|
+
* - Epoch timestamp in milliseconds when the job becomes eligible for dispatch. Defaults to enqueue time.
|
|
127
|
+
*/
|
|
128
|
+
scheduledAtMs?: number | undefined;
|
|
124
129
|
};
|
|
125
130
|
export type BackgroundJobPayload = {
|
|
126
131
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/background-jobs/types.js"],"names":[],"mappings":"AAEA;;GAEG;AACH;;;;GAIG;AACH
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/background-jobs/types.js"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* @property {string} [concurrencyKey] - Opaque non-empty key used to share a concurrency cap. Overrides any queue-derived cap.
|
|
17
17
|
* @property {number} [maxConcurrency] - Positive integer cap; must be paired with `concurrencyKey`.
|
|
18
18
|
* @property {boolean} [deduplicateWhileQueued] - When true (requires `concurrencyKey`), skip the enqueue if a still-queued job with the same `concurrencyKey` already exists, returning that job's id. Keeps an interval-scheduled recurring job (e.g. retention pruning) from piling up redundant queued rows when it runs slower than its interval or no worker is free.
|
|
19
|
+
* @property {number} [scheduledAtMs] - Epoch timestamp in milliseconds when the job becomes eligible for dispatch. Defaults to enqueue time.
|
|
19
20
|
*/
|
|
20
21
|
/**
|
|
21
22
|
* @typedef {object} BackgroundJobPayload
|
|
@@ -82,4 +83,4 @@
|
|
|
82
83
|
* @typedef {BackgroundJobHelloMessage | BackgroundJobReadyMessage | BackgroundJobDrainingMessage | BackgroundJobHeartbeatMessage | BackgroundJobEnqueueMessage | BackgroundJobEnqueuedMessage | BackgroundJobEnqueueErrorMessage | BackgroundJobJobMessage | BackgroundJobCompleteMessage | BackgroundJobFailedMessage | BackgroundJobUpdatedMessage | BackgroundJobUpdateErrorMessage} BackgroundJobSocketMessage
|
|
83
84
|
*/
|
|
84
85
|
export const nothing = {};
|
|
85
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
86
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYmFja2dyb3VuZC1qb2JzL3R5cGVzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWjs7R0FFRztBQUNIOzs7O0dBSUc7QUFDSDs7Ozs7Ozs7OztHQVVHO0FBQ0g7Ozs7Ozs7OztHQVNHO0FBQ0g7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FzQkc7QUFDSDs7Ozs7Ozs7OztHQVVHO0FBQ0g7O0dBRUc7QUFDSDs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0g7O0dBRUc7QUFFSCxNQUFNLENBQUMsTUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbi8qKlxuICogQHR5cGVkZWYge1wiaW5saW5lXCIgfCBcImZvcmtlZFwiIHwgXCJzcGF3bmVkXCJ9IEJhY2tncm91bmRKb2JFeGVjdXRpb25Nb2RlXG4gKi9cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gQmFja2dyb3VuZEpvYkhhbmRvZmZcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBoYW5kb2ZmSWQgLSBVbmlxdWUgaGFuZG9mZiBsZWFzZSBpZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBoYW5kZWRPZmZBdE1zIC0gVGltZSBoYW5kZWQgdG8gYSB3b3JrZXIgaW4gbXMuXG4gKi9cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gQmFja2dyb3VuZEpvYk9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7QmFja2dyb3VuZEpvYkV4ZWN1dGlvbk1vZGV9IFtleGVjdXRpb25Nb2RlXSAtIEhvdyB0aGUgam9iIHNob3VsZCBydW4uIERlZmF1bHRzIHRvIGBcImZvcmtlZFwiYC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2ZvcmtlZF0gLSBDb21wYXRpYmlsaXR5IGFsaWFzOiBgZmFsc2VgIG1hcHMgdG8gYFwiaW5saW5lXCJgIGFuZCBgdHJ1ZWAgbWFwcyB0byBgXCJmb3JrZWRcImAuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21heFJldHJpZXNdIC0gTWF4IHJldHJpZXMgZm9yIGEgZmFpbGVkIGpvYiBiZWZvcmUgaXQgaXMgbWFya2VkIGZhaWxlZC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbcXVldWVdIC0gUXVldWUgbmFtZS4gRGVmYXVsdHMgdG8gYFwiZGVmYXVsdFwiYC4gV2hlbiB0aGUgcXVldWUgaGFzIGEgY29uZmlndXJlZCBjYXAgaW4gYGJhY2tncm91bmRKb2JzLnF1ZXVlc2AsIHRoYXQgY2FwIGlzIGVuZm9yY2VkIGNsdXN0ZXItd2lkZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbY29uY3VycmVuY3lLZXldIC0gT3BhcXVlIG5vbi1lbXB0eSBrZXkgdXNlZCB0byBzaGFyZSBhIGNvbmN1cnJlbmN5IGNhcC4gT3ZlcnJpZGVzIGFueSBxdWV1ZS1kZXJpdmVkIGNhcC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWF4Q29uY3VycmVuY3ldIC0gUG9zaXRpdmUgaW50ZWdlciBjYXA7IG11c3QgYmUgcGFpcmVkIHdpdGggYGNvbmN1cnJlbmN5S2V5YC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2RlZHVwbGljYXRlV2hpbGVRdWV1ZWRdIC0gV2hlbiB0cnVlIChyZXF1aXJlcyBgY29uY3VycmVuY3lLZXlgKSwgc2tpcCB0aGUgZW5xdWV1ZSBpZiBhIHN0aWxsLXF1ZXVlZCBqb2Igd2l0aCB0aGUgc2FtZSBgY29uY3VycmVuY3lLZXlgIGFscmVhZHkgZXhpc3RzLCByZXR1cm5pbmcgdGhhdCBqb2IncyBpZC4gS2VlcHMgYW4gaW50ZXJ2YWwtc2NoZWR1bGVkIHJlY3VycmluZyBqb2IgKGUuZy4gcmV0ZW50aW9uIHBydW5pbmcpIGZyb20gcGlsaW5nIHVwIHJlZHVuZGFudCBxdWV1ZWQgcm93cyB3aGVuIGl0IHJ1bnMgc2xvd2VyIHRoYW4gaXRzIGludGVydmFsIG9yIG5vIHdvcmtlciBpcyBmcmVlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtzY2hlZHVsZWRBdE1zXSAtIEVwb2NoIHRpbWVzdGFtcCBpbiBtaWxsaXNlY29uZHMgd2hlbiB0aGUgam9iIGJlY29tZXMgZWxpZ2libGUgZm9yIGRpc3BhdGNoLiBEZWZhdWx0cyB0byBlbnF1ZXVlIHRpbWUuXG4gKi9cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gQmFja2dyb3VuZEpvYlBheWxvYWRcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbaWRdIC0gSm9iIGlkLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IGpvYk5hbWUgLSBKb2IgY2xhc3MgbmFtZS5cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8Pz59IFthcmdzXSAtIFNlcmlhbGl6ZWQgam9iIGFyZ3VtZW50cy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbaGFuZG9mZklkXSAtIFVuaXF1ZSBoYW5kb2ZmIGxlYXNlIGlkLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFt3b3JrZXJJZF0gLSBXb3JrZXIgaWQgaGFuZGxpbmcgdGhlIGpvYi5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbaGFuZGVkT2ZmQXRNc10gLSBUaW1lIGhhbmRlZCB0byBhIHdvcmtlciBpbiBtcy5cbiAqIEBwcm9wZXJ0eSB7QmFja2dyb3VuZEpvYk9wdGlvbnN9IFtvcHRpb25zXSAtIFJ1bnRpbWUgb3B0aW9ucy5cbiAqL1xuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBCYWNrZ3JvdW5kSm9iUm93XG4gKiBAcHJvcGVydHkge3N0cmluZ30gaWQgLSBKb2IgaWQuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gam9iTmFtZSAtIEpvYiBjbGFzcyBuYW1lLlxuICogQHByb3BlcnR5IHtBcnJheTw/Pn0gYXJncyAtIFNlcmlhbGl6ZWQgam9iIGFyZ3VtZW50cy5cbiAqIEBwcm9wZXJ0eSB7QmFja2dyb3VuZEpvYkV4ZWN1dGlvbk1vZGV9IGV4ZWN1dGlvbk1vZGUgLSBIb3cgdGhlIGpvYiBzaG91bGQgcnVuLlxuICogQHByb3BlcnR5IHtib29sZWFufSBmb3JrZWQgLSBDb21wYXRpYmlsaXR5IGZsYWc7IHRydWUgZm9yIG5vbi1pbmxpbmUgZXhlY3V0aW9uLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHF1ZXVlIC0gUXVldWUgbmFtZSAoZGVmYXVsdHMgdG8gYFwiZGVmYXVsdFwiYCkuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gc3RhdHVzIC0gQ3VycmVudCBqb2Igc3RhdHVzLlxuICogQHByb3BlcnR5IHtudW1iZXIgfCBudWxsfSBhdHRlbXB0cyAtIEZhaWx1cmUgYXR0ZW1wdHMgY291bnQuXG4gKiBAcHJvcGVydHkge251bWJlciB8IG51bGx9IG1heFJldHJpZXMgLSBNYXggcmV0cnkgYXR0ZW1wdHMuXG4gKiBAcHJvcGVydHkge251bWJlciB8IG51bGx9IHNjaGVkdWxlZEF0TXMgLSBOZXh0IHNjaGVkdWxlZCB0aW1lIGluIG1zLlxuICogQHByb3BlcnR5IHtudW1iZXIgfCBudWxsfSBjcmVhdGVkQXRNcyAtIENyZWF0aW9uIHRpbWUgaW4gbXMuXG4gKiBAcHJvcGVydHkge251bWJlciB8IG51bGx9IGhhbmRlZE9mZkF0TXMgLSBUaW1lIGhhbmRlZCB0byB3b3JrZXIgaW4gbXMuXG4gKiBAcHJvcGVydHkge3N0cmluZyB8IG51bGx9IGhhbmRvZmZJZCAtIFVuaXF1ZSBsYXRlc3QgaGFuZG9mZiBsZWFzZSBpZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyIHwgbnVsbH0gY29tcGxldGVkQXRNcyAtIENvbXBsZXRpb24gdGltZSBpbiBtcy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyIHwgbnVsbH0gZmFpbGVkQXRNcyAtIEZhaWx1cmUgdGltZSBpbiBtcy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyIHwgbnVsbH0gb3JwaGFuZWRBdE1zIC0gT3JwaGFuZWQgdGltZSBpbiBtcy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nIHwgbnVsbH0gd29ya2VySWQgLSBXb3JrZXIgaWQgaGFuZGxpbmcgdGhlIGpvYi5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nIHwgbnVsbH0gbGFzdEVycm9yIC0gTGFzdCBmYWlsdXJlIG1lc3NhZ2UuXG4gKiBAcHJvcGVydHkge3N0cmluZyB8IG51bGx9IGNvbmN1cnJlbmN5S2V5IC0gRHVyYWJsZSBjb25jdXJyZW5jeSBrZXkuXG4gKiBAcHJvcGVydHkge251bWJlciB8IG51bGx9IG1heENvbmN1cnJlbmN5IC0gRHVyYWJsZSBwZXIta2V5IGNhcC5cbiAqL1xuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBCYWNrZ3JvdW5kSm9iRmFpbHVyZUV2ZW50XG4gKiBAcHJvcGVydHkge0JhY2tncm91bmRKb2JSb3d9IGpvYiAtIFVwZGF0ZWQgam9iIHJvdyBhZnRlciBmYWlsdXJlIGhhbmRsaW5nLlxuICogQHByb3BlcnR5IHs/fSBlcnJvciAtIEZhaWx1cmUgZXJyb3IuXG4gKiBAcHJvcGVydHkge251bWJlciB8IG51bGx9IGF0dGVtcHRzIC0gVXBkYXRlZCBmYWlsdXJlIGF0dGVtcHRzIGNvdW50LlxuICogQHByb3BlcnR5IHtib29sZWFufSB0ZXJtaW5hbCAtIFdoZXRoZXIgdGhpcyBmYWlsdXJlIGVuZGVkIHRoZSBqb2IuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHdpbGxSZXRyeSAtIFdoZXRoZXIgdGhlIGpvYiB3YXMgcmV0dXJuZWQgdG8gdGhlIHF1ZXVlLlxuICogQHByb3BlcnR5IHtzdHJpbmcgfCB1bmRlZmluZWR9IGhhbmRvZmZJZCAtIEhhbmRvZmYgbGVhc2UgaWQgZnJvbSB0aGUgd29ya2VyIHJlcG9ydC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyIHwgdW5kZWZpbmVkfSBoYW5kZWRPZmZBdE1zIC0gSGFuZG9mZiB0aW1lc3RhbXAgZnJvbSB0aGUgd29ya2VyIHJlcG9ydC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nIHwgdW5kZWZpbmVkfSB3b3JrZXJJZCAtIFdvcmtlciBpZCBmcm9tIHRoZSB3b3JrZXIgcmVwb3J0LlxuICovXG4vKipcbiAqIEB0eXBlZGVmIHtcIndvcmtlclwiIHwgXCJjbGllbnRcIiB8IFwicmVwb3J0ZXJcIn0gQmFja2dyb3VuZEpvYlNvY2tldFJvbGVcbiAqL1xuLyoqXG4gKiBAdHlwZWRlZiB7e3R5cGU6IFwiaGVsbG9cIiwgcm9sZTogQmFja2dyb3VuZEpvYlNvY2tldFJvbGUsIHN1cHBvcnRzSGFuZG9mZklkUmVwb3J0aW5nPzogYm9vbGVhbiwgc3VwcG9ydHNIZWFydGJlYXQ/OiBib29sZWFuLCB3b3JrZXJJZD86IHN0cmluZ319IEJhY2tncm91bmRKb2JIZWxsb01lc3NhZ2VcbiAqIEB0eXBlZGVmIHt7dHlwZTogXCJyZWFkeVwiLCBhY2NlcHRzRm9ya2VkPzogYm9vbGVhbiwgYWNjZXB0c0lubGluZT86IGJvb2xlYW4sIGFjY2VwdHNTcGF3bmVkPzogYm9vbGVhbn19IEJhY2tncm91bmRKb2JSZWFkeU1lc3NhZ2VcbiAqIEB0eXBlZGVmIHt7dHlwZTogXCJkcmFpbmluZ1wifX0gQmFja2dyb3VuZEpvYkRyYWluaW5nTWVzc2FnZVxuICogQHR5cGVkZWYge3t0eXBlOiBcImhlYXJ0YmVhdFwiLCB3b3JrZXJJZD86IHN0cmluZ319IEJhY2tncm91bmRKb2JIZWFydGJlYXRNZXNzYWdlXG4gKiBAdHlwZWRlZiB7e3R5cGU6IFwiZW5xdWV1ZVwiLCBqb2JOYW1lOiBzdHJpbmcsIGFyZ3M/OiBBcnJheTw/Piwgb3B0aW9ucz86IEJhY2tncm91bmRKb2JPcHRpb25zfX0gQmFja2dyb3VuZEpvYkVucXVldWVNZXNzYWdlXG4gKiBAdHlwZWRlZiB7e3R5cGU6IFwiZW5xdWV1ZWRcIiwgam9iSWQ6IHN0cmluZ319IEJhY2tncm91bmRKb2JFbnF1ZXVlZE1lc3NhZ2VcbiAqIEB0eXBlZGVmIHt7dHlwZTogXCJlbnF1ZXVlLWVycm9yXCIsIGVycm9yPzogc3RyaW5nfX0gQmFja2dyb3VuZEpvYkVucXVldWVFcnJvck1lc3NhZ2VcbiAqIEB0eXBlZGVmIHt7dHlwZTogXCJqb2JcIiwgcGF5bG9hZDogQmFja2dyb3VuZEpvYlBheWxvYWR9fSBCYWNrZ3JvdW5kSm9iSm9iTWVzc2FnZVxuICogQHR5cGVkZWYge3t0eXBlOiBcImpvYi1jb21wbGV0ZVwiLCBqb2JJZDogc3RyaW5nLCBoYW5kb2ZmSWQ/OiBzdHJpbmcsIHdvcmtlcklkPzogc3RyaW5nLCBoYW5kZWRPZmZBdE1zPzogbnVtYmVyfX0gQmFja2dyb3VuZEpvYkNvbXBsZXRlTWVzc2FnZVxuICogQHR5cGVkZWYge3t0eXBlOiBcImpvYi1mYWlsZWRcIiwgam9iSWQ6IHN0cmluZywgZXJyb3I/OiA/LCBoYW5kb2ZmSWQ/OiBzdHJpbmcsIHdvcmtlcklkPzogc3RyaW5nLCBoYW5kZWRPZmZBdE1zPzogbnVtYmVyfX0gQmFja2dyb3VuZEpvYkZhaWxlZE1lc3NhZ2VcbiAqIEB0eXBlZGVmIHt7dHlwZTogXCJqb2ItdXBkYXRlZFwiLCBqb2JJZDogc3RyaW5nfX0gQmFja2dyb3VuZEpvYlVwZGF0ZWRNZXNzYWdlXG4gKiBAdHlwZWRlZiB7e3R5cGU6IFwiam9iLXVwZGF0ZS1lcnJvclwiLCBqb2JJZDogc3RyaW5nLCBlcnJvcj86IHN0cmluZ319IEJhY2tncm91bmRKb2JVcGRhdGVFcnJvck1lc3NhZ2VcbiAqL1xuLyoqXG4gKiBAdHlwZWRlZiB7QmFja2dyb3VuZEpvYkhlbGxvTWVzc2FnZSB8IEJhY2tncm91bmRKb2JSZWFkeU1lc3NhZ2UgfCBCYWNrZ3JvdW5kSm9iRHJhaW5pbmdNZXNzYWdlIHwgQmFja2dyb3VuZEpvYkhlYXJ0YmVhdE1lc3NhZ2UgfCBCYWNrZ3JvdW5kSm9iRW5xdWV1ZU1lc3NhZ2UgfCBCYWNrZ3JvdW5kSm9iRW5xdWV1ZWRNZXNzYWdlIHwgQmFja2dyb3VuZEpvYkVucXVldWVFcnJvck1lc3NhZ2UgfCBCYWNrZ3JvdW5kSm9iSm9iTWVzc2FnZSB8IEJhY2tncm91bmRKb2JDb21wbGV0ZU1lc3NhZ2UgfCBCYWNrZ3JvdW5kSm9iRmFpbGVkTWVzc2FnZSB8IEJhY2tncm91bmRKb2JVcGRhdGVkTWVzc2FnZSB8IEJhY2tncm91bmRKb2JVcGRhdGVFcnJvck1lc3NhZ2V9IEJhY2tncm91bmRKb2JTb2NrZXRNZXNzYWdlXG4gKi9cblxuZXhwb3J0IGNvbnN0IG5vdGhpbmcgPSB7fVxuIl19
|
package/package.json
CHANGED
|
@@ -6,6 +6,7 @@ import BackgroundJobsScheduler from "./scheduler.js"
|
|
|
6
6
|
import BackgroundJobsStore from "./store.js"
|
|
7
7
|
import Logger from "../logger.js"
|
|
8
8
|
import PruneTerminalBackgroundJobsJob from "../jobs/prune-terminal-background-jobs.js"
|
|
9
|
+
import VelociousError from "../velocious-error.js"
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Channel used by `background-jobs-main` to coordinate dispatch wake-ups
|
|
@@ -683,7 +684,21 @@ export default class BackgroundJobsMain {
|
|
|
683
684
|
this._notifyEnqueued()
|
|
684
685
|
await this._drain()
|
|
685
686
|
} catch (error) {
|
|
686
|
-
|
|
687
|
+
if (error instanceof VelociousError && error.safeToExpose) {
|
|
688
|
+
jsonSocket.send({type: "enqueue-error", error: error.message})
|
|
689
|
+
return
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
const normalizedError = error instanceof Error ? error : new Error(String(error))
|
|
693
|
+
const payload = {
|
|
694
|
+
context: {jobName: message.jobName, stage: "background-job-enqueue"},
|
|
695
|
+
error: normalizedError
|
|
696
|
+
}
|
|
697
|
+
const errorEvents = this.configuration.getErrorEvents()
|
|
698
|
+
|
|
699
|
+
this.logger.error(() => ["Failed to enqueue background job:", normalizedError])
|
|
700
|
+
errorEvents.emit("framework-error", payload)
|
|
701
|
+
errorEvents.emit("all-error", {...payload, errorType: "framework-error"})
|
|
687
702
|
jsonSocket.send({type: "enqueue-error", error: "Failed to enqueue job"})
|
|
688
703
|
}
|
|
689
704
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import {randomUUID} from "crypto"
|
|
4
4
|
import Logger from "../logger.js"
|
|
5
5
|
import TableData from "../database/table-data/index.js"
|
|
6
|
+
import VelociousError from "../velocious-error.js"
|
|
6
7
|
import BackgroundJobRecord from "./job-record.js"
|
|
7
8
|
import normalizeBackgroundJobError from "./normalize-error.js"
|
|
8
9
|
|
|
@@ -99,6 +100,7 @@ export default class BackgroundJobsStore {
|
|
|
99
100
|
const now = Date.now()
|
|
100
101
|
const executionMode = this._normalizeExecutionMode(options)
|
|
101
102
|
const maxRetries = this._normalizeMaxRetries(options?.maxRetries)
|
|
103
|
+
const scheduledAtMs = this._normalizeScheduledAtMs(options?.scheduledAtMs, now)
|
|
102
104
|
const argsJson = JSON.stringify(args || [])
|
|
103
105
|
const queue = this._normalizeQueue(options)
|
|
104
106
|
const concurrency = this._resolveConcurrency(options, queue)
|
|
@@ -141,7 +143,7 @@ export default class BackgroundJobsStore {
|
|
|
141
143
|
max_retries: maxRetries,
|
|
142
144
|
attempts: 0,
|
|
143
145
|
status: "queued",
|
|
144
|
-
scheduled_at_ms:
|
|
146
|
+
scheduled_at_ms: scheduledAtMs,
|
|
145
147
|
created_at_ms: now,
|
|
146
148
|
concurrency_key: concurrency?.concurrencyKey || null,
|
|
147
149
|
max_concurrency: concurrency?.maxConcurrency || null
|
|
@@ -726,6 +728,19 @@ export default class BackgroundJobsStore {
|
|
|
726
728
|
return DEFAULT_MAX_RETRIES
|
|
727
729
|
}
|
|
728
730
|
|
|
731
|
+
/**
|
|
732
|
+
* Runs normalize scheduled at ms.
|
|
733
|
+
* @param {number | undefined} scheduledAtMs - Requested dispatch timestamp.
|
|
734
|
+
* @param {number} defaultScheduledAtMs - Default dispatch timestamp.
|
|
735
|
+
* @returns {number} - Dispatch timestamp.
|
|
736
|
+
*/
|
|
737
|
+
_normalizeScheduledAtMs(scheduledAtMs, defaultScheduledAtMs) {
|
|
738
|
+
if (scheduledAtMs === undefined) return defaultScheduledAtMs
|
|
739
|
+
if (Number.isSafeInteger(scheduledAtMs) && scheduledAtMs >= 0) return scheduledAtMs
|
|
740
|
+
|
|
741
|
+
throw VelociousError.safe("background job scheduledAtMs must be a non-negative safe integer")
|
|
742
|
+
}
|
|
743
|
+
|
|
729
744
|
async _ensureSchema() {
|
|
730
745
|
await this._withDb(async (db) => {
|
|
731
746
|
await this._ensureMigrationsTable(db)
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* @property {string} [concurrencyKey] - Opaque non-empty key used to share a concurrency cap. Overrides any queue-derived cap.
|
|
18
18
|
* @property {number} [maxConcurrency] - Positive integer cap; must be paired with `concurrencyKey`.
|
|
19
19
|
* @property {boolean} [deduplicateWhileQueued] - When true (requires `concurrencyKey`), skip the enqueue if a still-queued job with the same `concurrencyKey` already exists, returning that job's id. Keeps an interval-scheduled recurring job (e.g. retention pruning) from piling up redundant queued rows when it runs slower than its interval or no worker is free.
|
|
20
|
+
* @property {number} [scheduledAtMs] - Epoch timestamp in milliseconds when the job becomes eligible for dispatch. Defaults to enqueue time.
|
|
20
21
|
*/
|
|
21
22
|
/**
|
|
22
23
|
* @typedef {object} BackgroundJobPayload
|