psdev-task-manager 1.1.4 → 1.1.6

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.
@@ -0,0 +1,7 @@
1
+ node_modules
2
+ dist
3
+ build
4
+ coverage
5
+ *.min.js
6
+ package-lock.json
7
+
@@ -0,0 +1,16 @@
1
+ {
2
+ "singleQuote": true,
3
+ "trailingComma": "es5",
4
+ "printWidth": 100,
5
+ "tabWidth": 2,
6
+ "semi": true,
7
+ "bracketSpacing": true,
8
+ "bracketSameLine": false,
9
+ "arrowParens": "avoid",
10
+ "endOfLine": "lf",
11
+ "quoteProps": "as-needed",
12
+ "jsxSingleQuote": false,
13
+ "requirePragma": false,
14
+ "insertPragma": false,
15
+ "proseWrap": "preserve"
16
+ }
package/README.md CHANGED
@@ -1,2 +1,3 @@
1
1
  # task-manager
2
+
2
3
  Task manager library
@@ -7,5 +7,4 @@ module.exports = {
7
7
  ...require('./taskManager'),
8
8
  ...require('./utils'),
9
9
  ...require('./tasks'),
10
-
11
10
  };
@@ -2,5 +2,5 @@ module.exports = {
2
2
  ...require('./handler'),
3
3
  ...require('./childScheduler'),
4
4
  ...require('./parentStatusManager'),
5
- ...require('./utils')
5
+ ...require('./utils'),
6
6
  };
@@ -1,6 +1,6 @@
1
1
  const { withDuration, withSuccessRateLogs } = require('psdev-utils');
2
2
 
3
- const { TASK_STATUS, CRON_JOB_MAX_DURATION_SEC } = require('./consts');
3
+ const { TASK_STATUS, CRON_JOB_MAX_DURATION_SEC, TASK_MAX_TRIES } = require('./consts');
4
4
  const { scheduleChildTasksAndUpdateParent } = require('./parentChildTasks/handler');
5
5
  const {
6
6
  saveTaskResultToAdditionalCollection,
@@ -136,7 +136,7 @@ function taskManager() {
136
136
  return {
137
137
  schedule: insertNewTask,
138
138
  scheduleInBulk: bulkInsertTasks,
139
- processTask : (...args) => {
139
+ processTask: (...args) => {
140
140
  const requestName = `processTask_${args[0].name}`; //To get success rate analysis per task
141
141
  return withSuccessRateLogs(requestName, () => processTask(...args));
142
142
  },
@@ -1,29 +1,29 @@
1
1
  const TASKS = {
2
- TEST_TASK: {
3
- name: 'TestTask',
4
- getIdentifier: (task) => (task),
5
- process: (task) => {
6
- const data = task.data || {};
7
- let error;
8
- if (data.retries){
9
- error = task.error ? Number(task.error) - 1 : data.retries - 1;
10
- }
11
- if (data.shouldFail && (!error || error > 0)){
12
- throw new Error(error?.toString() || 'Test error');
13
- }
14
- return 'test';
15
- },
16
- shouldSkipCheck: (task) => task.data.shouldSkip,
17
- estimatedDurationSec:2,
2
+ TEST_TASK: {
3
+ name: 'TestTask',
4
+ getIdentifier: task => task,
5
+ process: task => {
6
+ const data = task.data || {};
7
+ let error;
8
+ if (data.retries) {
9
+ error = task.error ? Number(task.error) - 1 : data.retries - 1;
10
+ }
11
+ if (data.shouldFail && (!error || error > 0)) {
12
+ throw new Error(error?.toString() || 'Test error');
13
+ }
14
+ return 'test';
18
15
  },
19
- BAD_TASK: {
20
- name: 'BadTask',
21
- getIdentifier: () => true,
22
- process: () => 'test',
23
- shouldSkipCheck: () => false,
24
- },
25
- };
16
+ shouldSkipCheck: task => task.data.shouldSkip,
17
+ estimatedDurationSec: 2,
18
+ },
19
+ BAD_TASK: {
20
+ name: 'BadTask',
21
+ getIdentifier: () => true,
22
+ process: () => 'test',
23
+ shouldSkipCheck: () => false,
24
+ },
25
+ };
26
26
 
27
- module.exports = {
28
- TASKS,
29
- };
27
+ module.exports = {
28
+ TASKS,
29
+ };
@@ -44,7 +44,7 @@ async function createCollectionIfMissing(
44
44
  if (collectionType === 'singleItem') {
45
45
  createDataCollectionOptions.plugins = [
46
46
  {
47
- type: "SINGLE_ITEM",
47
+ type: 'SINGLE_ITEM',
48
48
  singleItemOptions: {},
49
49
  },
50
50
  ];
@@ -171,15 +171,13 @@ const filterScheduledTasksByStatus = (tasks, tasksConfig) => {
171
171
  console.log(
172
172
  `filterScheduledTasksByStatus: tasks count: ${tasks.length} tasksConfig: ${JSON.stringify(tasksConfig)}`
173
173
  );
174
- const shouldIncludeTask = (task, tasksConfig) => {
174
+ const shouldIncludeTask = (task, taskConfig) => {
175
175
  console.log(`filterScheduledTasksByStatus: task: ${JSON.stringify(task)}`);
176
- console.log(
177
- `filterScheduledTasksByStatus: taskConfig: ${JSON.stringify(taskConfig)}`
178
- );
176
+ console.log(`filterScheduledTasksByStatus: taskConfig: ${JSON.stringify(taskConfig)}`);
179
177
  const { status } = task;
180
178
  if (status === TASK_STATUS.IN_PROGRESS) {
181
179
  //Only include parent tasks that are in progress, to continue running next children
182
- return isParentTask(task, tasksConfig[task.name]);
180
+ return isParentTask(task, taskConfig);
183
181
  }
184
182
  if (status === TASK_STATUS.FAILED) {
185
183
  // Exclude if it's a parent task, if parent task failed, we don't retry it anymore
@@ -233,7 +231,11 @@ const getTaskScheduledChildren = async parentTaskId => {
233
231
  };
234
232
 
235
233
  const getTasksToProcess = ({ scheduledTasks, tasksConfig, maxDuration }) => {
236
- console.log('getTasksToProcess:', { scheduledTasksCount: scheduledTasks.length, tasksConfig, maxDuration });
234
+ console.log('getTasksToProcess:', {
235
+ scheduledTasksCount: scheduledTasks.length,
236
+ tasksConfig,
237
+ maxDuration,
238
+ });
237
239
  const tasksToProcess = [];
238
240
  let totalDuration = 0;
239
241
  console.log(`tasksConfig is : ${JSON.stringify(tasksConfig)}`);
@@ -0,0 +1,113 @@
1
+ const js = require('@eslint/js');
2
+ const prettierConfig = require('eslint-config-prettier');
3
+ const importPlugin = require('eslint-plugin-import');
4
+ const prettier = require('eslint-plugin-prettier');
5
+ const promisePlugin = require('eslint-plugin-promise');
6
+ const globals = require('globals');
7
+
8
+ module.exports = [
9
+ // Recommended base configurations
10
+ js.configs.recommended,
11
+ prettierConfig,
12
+
13
+ // Main configuration
14
+ {
15
+ files: ['**/*.js'],
16
+ languageOptions: {
17
+ ecmaVersion: 2021,
18
+ sourceType: 'commonjs',
19
+ globals: {
20
+ ...globals.node,
21
+ ...globals.es2021,
22
+ ...globals.jest,
23
+ },
24
+ },
25
+ plugins: {
26
+ prettier,
27
+ import: importPlugin,
28
+ promise: promisePlugin,
29
+ },
30
+ rules: {
31
+ // Error prevention
32
+ 'no-var': 'error',
33
+ 'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
34
+ 'no-console': ['warn', { allow: ['warn', 'error', 'log', 'info'] }],
35
+ 'no-debugger': 'warn',
36
+ 'no-duplicate-imports': 'error',
37
+ 'no-unused-expressions': ['error', { allowShortCircuit: true, allowTernary: true }],
38
+ 'no-use-before-define': ['error', { functions: false }],
39
+
40
+ // Best practices
41
+ 'prefer-const': 'error',
42
+ 'no-const-assign': 'error',
43
+ 'prefer-arrow-callback': 'error',
44
+ 'arrow-body-style': ['error', 'as-needed'],
45
+ 'no-return-await': 'off',
46
+ 'require-await': 'warn',
47
+
48
+ // Import rules
49
+ 'import/order': [
50
+ 'error',
51
+ {
52
+ groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
53
+ 'newlines-between': 'always',
54
+ alphabetize: { order: 'asc', caseInsensitive: true },
55
+ },
56
+ ],
57
+ 'import/no-unresolved': 'error',
58
+ 'import/no-duplicates': 'error',
59
+ 'import/no-commonjs': 'off',
60
+ 'import/no-dynamic-require': 'off',
61
+
62
+ // Promise rules
63
+ 'promise/always-return': 'off',
64
+ 'promise/no-return-wrap': 'error',
65
+ 'promise/param-names': 'error',
66
+ 'promise/catch-or-return': 'error',
67
+ 'promise/no-native': 'off',
68
+ 'promise/no-callback-in-promise': 'warn',
69
+ 'promise/no-promise-in-callback': 'warn',
70
+ 'promise/no-nesting': 'warn',
71
+
72
+ // Prettier rules
73
+ 'prettier/prettier': [
74
+ 'error',
75
+ {
76
+ singleQuote: true,
77
+ trailingComma: 'es5',
78
+ printWidth: 100,
79
+ tabWidth: 2,
80
+ semi: true,
81
+ bracketSpacing: true,
82
+ arrowParens: 'avoid',
83
+ endOfLine: 'lf',
84
+ },
85
+ ],
86
+ },
87
+ settings: {
88
+ 'import/resolver': {
89
+ node: {
90
+ extensions: ['.js', '.jsx', '.ts', '.tsx'],
91
+ },
92
+ },
93
+ },
94
+ },
95
+
96
+ // Test files override
97
+ {
98
+ files: ['**/*.test.js', '**/*.spec.js'],
99
+ languageOptions: {
100
+ globals: {
101
+ ...globals.jest,
102
+ },
103
+ },
104
+ rules: {
105
+ 'no-console': 'off',
106
+ },
107
+ },
108
+
109
+ // Ignore patterns
110
+ {
111
+ ignores: ['node_modules/**', 'dist/**', 'build/**', 'coverage/**', '*.min.js'],
112
+ },
113
+ ];
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  module.exports = {
2
2
  ...require('./backend'),
3
- ...require('./public')
3
+ ...require('./public'),
4
4
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "psdev-task-manager",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "description": "Task manager library",
5
5
  "keywords": [
6
6
  "task-manager"
@@ -18,11 +18,27 @@
18
18
  "type": "commonjs",
19
19
  "main": "index.js",
20
20
  "scripts": {
21
- "test": "jest"
21
+ "test": "jest",
22
+ "lint": "eslint .",
23
+ "lint:fix": "eslint . --fix",
24
+ "format": "prettier --write \"**/*.{js,json,md}\"",
25
+ "format:check": "prettier --check \"**/*.{js,json,md}\"",
26
+ "prepare": "husky"
22
27
  },
23
28
  "dependencies": {
24
29
  "@wix/data": "^1.0.273",
25
30
  "@wix/essentials": "^0.1.27",
26
- "psdev-utils": "1.0.2"
31
+ "psdev-utils": "1.1.0"
32
+ },
33
+ "devDependencies": {
34
+ "@eslint/js": "^9.12.0",
35
+ "eslint": "^9.12.0",
36
+ "eslint-config-prettier": "^9.1.0",
37
+ "eslint-plugin-import": "^2.30.0",
38
+ "eslint-plugin-prettier": "^5.2.1",
39
+ "eslint-plugin-promise": "^7.1.0",
40
+ "globals": "^15.10.0",
41
+ "husky": "^9.1.6",
42
+ "prettier": "^3.3.3"
27
43
  }
28
44
  }
package/public/consts.js CHANGED
@@ -26,4 +26,4 @@ const COLLECTIONS_FIELDS = {
26
26
  module.exports = {
27
27
  COLLECTIONS,
28
28
  COLLECTIONS_FIELDS,
29
- };
29
+ };
package/.eslintrc.json DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "extends": ["plugin:@wix/cli/recommended"]
3
- }
@@ -1,115 +0,0 @@
1
- # The Backend Code Folder
2
-
3
- This folder contains the backend code files for your site. These files correspond to the ones found in the [**Backend**](https://support.wix.com/en/article/velo-working-with-the-velo-sidebar#backend) section of the **Public & Backend**
4
- ![image](https://user-images.githubusercontent.com/89579857/184862813-e55cdd98-b723-4d64-b73c-593eb9af21c7.png) tab in the Velo sidebar. Add the following files to this folder to include them in your site:
5
- + [**Web Modules:**](https://support.wix.com/en/article/velo-web-modules-calling-backend-code-from-the-frontend)
6
- These are files that allow you to expose functions in your site's backend that you can run in your frontend code. These files require a `.jsw` file extension.
7
- >**Note:**
8
- >You can't change [web module permissions](https://support.wix.com/en/article/velo-about-web-module-permissions) in Wix editors when using Git Integration & Wix CLI. Instead, use the [permissions.json](#permissionsjson) file to set function permissions.
9
-
10
- + **data.js**
11
- A file for [adding data hooks](https://support.wix.com/en/article/velo-using-data-hooks) to your site's collections.
12
-
13
- + **routers.js**
14
- A file for implementing [routing and sitemap](https://support.wix.com/en/article/velo-about-routers#routing-code) functionality for your site.
15
-
16
- + **events.js**
17
- A file for implementing your site's [backend event handlers](https://support.wix.com/en/article/velo-backend-events).
18
-
19
- + **http-functions.js**
20
- A file for implementing [HTTP endpoints](https://www.wix.com/velo/reference/wix-http-functions/introduction) that are exposed on your site.
21
-
22
- + **jobs.config**
23
- A file for [scheduling recurring jobs](https://support.wix.com/en/article/velo-scheduling-recurring-jobs). Jobs consist of other backend code that's run at regular intervals.
24
-
25
- + **General backend files**
26
- JavaScript code files. You can import code from these files into any other backend file on your site. These files require a `.js` file extension.
27
-
28
- Use the following syntax to import code from backend files:
29
- ```js
30
- import { myFunctionName } from 'backend/myFileName';
31
- ```
32
- Trying to import from the relative path in your site's repo doesn't work.
33
-
34
- Learn more about [this repo's file structure](https://support.wix.com/en/article/velo-understanding-your-sites-github-repository-beta).
35
-
36
- ## permissions.json
37
- This file defines [permissions](https://support.wix.com/en/article/velo-about-web-module-permissions) for the functions in your web module files. The file contains a key, `"web-methods"`, whose value is an object that can contain keys named after the web module files in your `backend` folder. Name these keys with the following syntax: `"backend/{path to file}myFile.jsw"`. The value for each file name key is an object that can contain keys named after the functions in that file. Each function key has a value with the following format:
38
- ```js
39
- "backend/myFile.jsw": {
40
- "siteOwner" : {
41
- "invoke" : // Boolean
42
- },
43
- "siteMember" : {
44
- "invoke" : // Boolean
45
- },
46
- "anonymous" : {
47
- "invoke" : // Boolean
48
- }
49
- }
50
- ```
51
- These values reflect the different levels of web module function permissions. You can set them using the following options:
52
- | |`siteOwner`|`siteMember`|`anonymous`|
53
- |-|-----------|------------|-----------|
54
- |Owner-only access| `true` | `false` | `false`|
55
- |Site member access| `true` | `true` | `false`|
56
- |Anyone can access| `true` | `true`| `true`|
57
-
58
- The `"web-methods"` object must also contain a `"*"` key. The value for this key defines the default permissions that are applied to any function whose permissions you don't set manually.
59
-
60
- Here is an example `permissions.json` file for a site with a backend file called `helperFunctions.jsw`. The file's functions are called `calculate`, `fetchData`, and `syncWithServer`. In this case anyone can call `calculate`, site members can call `syncWithServer`, and only site owners can call `fetchData`.
61
-
62
- ```json
63
- {
64
- "web-methods": {
65
- "*": {
66
- "*": {
67
- "siteOwner": {
68
- "invoke": true
69
- },
70
- "siteMember": {
71
- "invoke": true
72
- },
73
- "anonymous": {
74
- "invoke": true
75
- }
76
- }
77
- },
78
- "backend/helperFunctions.jsw": {
79
- "calculate": {
80
- "siteOwner": {
81
- "invoke": true
82
- },
83
- "siteMember": {
84
- "invoke": true
85
- },
86
- "anonymous": {
87
- "invoke": true
88
- }
89
- },
90
- "fetchData": {
91
- "siteOwner": {
92
- "invoke": true
93
- },
94
- "siteMember": {
95
- "invoke": false
96
- },
97
- "anonymous": {
98
- "invoke": false
99
- }
100
- },
101
- "syncWithServer": {
102
- "siteOwner": {
103
- "invoke": true
104
- },
105
- "siteMember": {
106
- "invoke": true
107
- },
108
- "anonymous": {
109
- "invoke": false
110
- }
111
- }
112
- }
113
- }
114
- }
115
- ```
@@ -1,40 +0,0 @@
1
- import { response } from "wix-http-functions";
2
- import { rootMethods } from './rootMethods';
3
-
4
- export async function post_getResult(request) {
5
- let options = {
6
- headers: { "Content-Type": "application/json" }
7
- };
8
-
9
- try {
10
- const methodsToExecute = await request.body.text();
11
- /**
12
- * Dynamically executes a method string from the request body.
13
- *
14
- * - `methodsToExecute` is expected to be a string, e.g.:
15
- * "taskManager().schedule({ name: 'BadTask', data: {}, type: 'scheduled' })"
16
- * - Only root methods defined in `rootMethods` are allowed.
17
- * - We use `new Function(...)` to create a scoped function so that the
18
- * root methods (taskManager, wixData, etc.) are available in the execution context.
19
- * - The result of executing the string is returned and sent in the response.
20
- *
21
- * ⚠️ Warning: This executes arbitrary code strings, so only trusted input
22
- * should be passed here.
23
- */
24
- const result = await (new Function(...Object.keys(rootMethods), `return ${methodsToExecute}`))(
25
- ...Object.values(rootMethods)
26
- );
27
-
28
-
29
- options.body = { result };
30
- options.status = 200;
31
-
32
- } catch (err) {
33
- options.body = {
34
- message: err.message
35
- };
36
- options.status = 500;
37
- }
38
-
39
- return response(options);
40
- }
@@ -1,17 +0,0 @@
1
- {
2
- "web-methods": {
3
- "*": {
4
- "*": {
5
- "siteOwner": {
6
- "invoke": true
7
- },
8
- "siteMember": {
9
- "invoke": true
10
- },
11
- "anonymous": {
12
- "invoke": true
13
- }
14
- }
15
- }
16
- }
17
- }
@@ -1,8 +0,0 @@
1
- // rootMethods.js
2
- import { taskManager } from 'psdev-task-manager';
3
- import wixData from 'wix-data';
4
-
5
- export const rootMethods = {
6
- taskManager,
7
- wixData
8
- };
@@ -1,10 +0,0 @@
1
- // API Reference: https://www.wix.com/velo/reference/api-overview/introduction
2
- // “Hello, World!” Example: https://learn-code.wix.com/en/article/hello-world
3
-
4
- $w.onReady(function () {
5
- // Write your JavaScript here
6
-
7
- // To select an element by ID use: $w('#elementID')
8
-
9
- // Click 'Preview' to run your code
10
- });
@@ -1,21 +0,0 @@
1
- # The Page Code Folder
2
-
3
- This folder contains code files for each of the pages on your site as well as the [masterpage.js](https://support.wix.com/en/article/velo-working-with-the-velo-sidebar#global-site) file. The code you add to these files runs when visitors open pages on your site. These files correspond to the ones found in the [**Main Pages**](https://support.wix.com/en/article/velo-working-with-the-velo-sidebar#main-pages) section of the **Page Code** ![image](https://user-images.githubusercontent.com/89579857/184645988-6d4ee6d3-34ab-45bc-b914-5779a7de0cad.png) tab in the Velo sidebar.
4
-
5
- When you add a page to your site in a Wix editor in your browser, a code file for that page gets added to your repo. The name of the file has 2 components: the name of the page that you define when you create it, and an internal ID string. The sections are separated by a period.
6
-
7
- ![image](https://user-images.githubusercontent.com/89579857/188305074-6e2ee718-13b8-435d-9c75-bcb126f35718.png)
8
-
9
- When you [add a dynamic page](https://support.wix.com/en/article/content-manager-about-dynamic-pages#adding-dynamic-pages) to your site 2 code files are added to the site's repo corresponding to the dynamic list and dynamic item pages.
10
-
11
- When you open a page's code file, you see the same sample code that appears in these code files in Wix editors in your browser.
12
-
13
- ![image](https://user-images.githubusercontent.com/89579857/184646571-1e14f166-2b86-4f21-bf57-83468251bca8.png)
14
-
15
- When you delete a page in a Wix editor in your browser, the page's corresponding code file is deleted from your repo.
16
-
17
- > **Note:**
18
- > * You can't create new code files for pages from your IDE. To add a file, create a new page for your site in a Wix editor in your browser, and [sync](https://support.wix.com/en/article/velo-working-with-the-local-editor-beta#sync-design-changes-to-your-ide) your site with your local IDE.
19
- > * Do not rename code files for pages. Wix uses these file names to associate the files with the appropriate pages on your site. If you rename a file, your code is ignored and a new code file is created for the page.
20
-
21
- Learn more about [this repo's file structure](https://support.wix.com/en/article/velo-understanding-your-sites-github-repository-beta).
@@ -1,10 +0,0 @@
1
- // API Reference: https://www.wix.com/velo/reference/api-overview/introduction
2
- // “Hello, World!” Example: https://learn-code.wix.com/en/article/hello-world
3
-
4
- $w.onReady(function () {
5
- // Write your JavaScript here
6
-
7
- // To select an element by ID use: $w('#elementID')
8
-
9
- // Click 'Preview' to run your code
10
- });
@@ -1,11 +0,0 @@
1
- # The Public Code Folder
2
-
3
- This folder contains the public code files for your site. These files correspond to the ones found in the [**Public**](https://support.wix.com/en/article/velo-working-with-the-velo-sidebar#public) section of the **Public & Backend** ![image](https://user-images.githubusercontent.com/89579857/184873215-d6042ace-4d20-40f2-ad37-1b1911302f96.png) tab in the Velo sidebar. You can import code from these files into any other file on your site.
4
-
5
- Use the following syntax to import code from public files:
6
- ```js
7
- import { myFunctionName } from 'public/myFileName';
8
- ```
9
- Trying to import from the relative path in your site's repo doesn't work.
10
-
11
- Learn more about [this repo's file structure](https://support.wix.com/en/article/velo-understanding-your-sites-github-repository-beta).
@@ -1,3 +0,0 @@
1
- export const COLLECTIONS = {
2
- TASKS: 'Tasks',
3
- };