Browse Source

Merge branch 'dev' of https://github.com/automaapp/automa into dev

Ahmad Kholid 1 year ago
parent
commit
ebe93ef133

+ 31 - 25
src/content/blocksHandler/handlerForms.js

@@ -1,6 +1,7 @@
-import { sendMessage } from '@/utils/message';
 import handleFormElement from '@/utils/handleFormElement';
+import { sendMessage } from '@/utils/message';
 import handleSelector, { markElement } from '../handleSelector';
+import synchronizedLock from '../synchronizedLock';
 
 async function forms(block) {
   const { data } = block;
@@ -24,38 +25,43 @@ async function forms(block) {
 
   async function typeText(element) {
     if (block.debugMode && data.type === 'text-field') {
+      // get lock
+      await synchronizedLock.getLock();
       element.focus?.();
 
-      if (data.clearValue) {
-        const backspaceCommands = new Array(element.value?.length ?? 0).fill({
-          type: 'rawKeyDown',
-          unmodifiedText: 'Delete',
-          text: 'Delete',
-          windowsVirtualKeyCode: 46,
-        });
+      try {
+        if (data.clearValue) {
+          const backspaceCommands = new Array(element.value?.length ?? 0).fill({
+            type: 'rawKeyDown',
+            unmodifiedText: 'Delete',
+            text: 'Delete',
+            windowsVirtualKeyCode: 46,
+          });
+
+          await sendMessage(
+            'debugger:type',
+            { commands: backspaceCommands, tabId: block.activeTabId, delay: 0 },
+            'background'
+          );
+        }
 
+        const commands = data.value.split('').map((char) => ({
+          type: 'keyDown',
+          text: char === '\n' ? '\r' : char,
+        }));
+        const typeDelay = +block.data.delay;
         await sendMessage(
           'debugger:type',
-          { commands: backspaceCommands, tabId: block.activeTabId, delay: 0 },
+          {
+            commands,
+            tabId: block.activeTabId,
+            delay: Number.isNaN(typeDelay) ? 0 : typeDelay,
+          },
           'background'
         );
+      } finally {
+        synchronizedLock.releaseLock();
       }
-
-      const commands = data.value.split('').map((char) => ({
-        type: 'keyDown',
-        text: char === '\n' ? '\r' : char,
-      }));
-      const typeDelay = +block.data.delay;
-      await sendMessage(
-        'debugger:type',
-        {
-          commands,
-          tabId: block.activeTabId,
-          delay: Number.isNaN(typeDelay) ? 0 : typeDelay,
-        },
-        'background'
-      );
-
       return;
     }
 

+ 0 - 19
src/content/index.js

@@ -240,19 +240,9 @@ async function messageListener({ data, source }) {
 
   automa('content');
 
-  let locked = false;
-  const queue = [];
-
   browser.runtime.onMessage.addListener(async (data) => {
     const asyncExecuteBlock = async (block) => {
-      if (locked) {
-        return new Promise((resolve, reject) => {
-          queue.push([block, resolve, reject]);
-        });
-      }
-
       try {
-        locked = true;
         const res = await executeBlock(block);
         return res;
       } catch (error) {
@@ -275,20 +265,11 @@ async function messageListener({ data, source }) {
 
         await blocksHandler().loopData(loopBlock);
         return executeBlock(block);
-      } finally {
-        locked = false;
       }
     };
 
     if (data.isBlock) {
       const res = await asyncExecuteBlock(data);
-      while (queue.length) {
-        const [block, resolve, reject] = queue.shift();
-        requestAnimationFrame(() => {
-          asyncExecuteBlock(block).then(resolve).catch(reject);
-        });
-      }
-
       return res;
     }
 

+ 34 - 0
src/content/synchronizedLock.js

@@ -0,0 +1,34 @@
+class SynchronizedLock {
+  constructor() {
+    this.lock = false;
+    this.queue = [];
+  }
+
+  async getLock(timeout = 10000) {
+    while (this.lock) {
+      await new Promise((resolve) => {
+        this.queue.push(resolve);
+        setTimeout(() => {
+          const index = this.queue.indexOf(resolve);
+          if (index !== -1) {
+            this.queue.splice(index, 1);
+            console.warn('SynchronizedLock timeout');
+            resolve();
+          }
+        }, timeout);
+      });
+    }
+
+    this.lock = true;
+  }
+
+  releaseLock() {
+    this.lock = false;
+    const resolve = this.queue.shift();
+    if (resolve) resolve();
+  }
+}
+
+const synchronizedLock = new SynchronizedLock();
+
+export default synchronizedLock;

+ 6 - 0
src/workflowEngine/WorkflowEngine.js

@@ -481,6 +481,12 @@ class WorkflowEngine {
       const { table, variables } = this.referenceData;
       const tableId = this.workflow.connectedTable;
 
+      // Merge all table and variables from all workflows
+      Object.values(this.referenceData.workflow).forEach((data) => {
+        Object.assign(table, data.table);
+        Object.assign(variables, data.variables);
+      });
+
       await dbStorage.transaction(
         'rw',
         dbStorage.tablesItems,

+ 9 - 8
src/workflowEngine/blocksHandler/handlerExecuteWorkflow.js

@@ -2,6 +2,7 @@ import browser from 'webextension-polyfill';
 import { isWhitespace, parseJSON } from '@/utils/helper';
 import decryptFlow, { getWorkflowPass } from '@/utils/decryptFlow';
 import convertWorkflowData from '@/utils/convertWorkflowData';
+import { nanoid } from 'nanoid';
 import WorkflowEngine from '../WorkflowEngine';
 
 function workflowListener(workflow, options) {
@@ -115,14 +116,14 @@ async function executeWorkflow({ id: blockId, data }, { refData }) {
         this.childWorkflowId = engine.id;
       },
       onDestroyed: (engine) => {
-        if (data.executeId) {
-          const { variables, table } = engine.referenceData;
-
-          this.engine.referenceData.workflow[data.executeId] = {
-            table,
-            variables,
-          };
-        }
+        const { variables, table } = engine.referenceData;
+
+        this.engine.referenceData.workflow[
+          data.executeId || `${engine.id}-${nanoid(8)}`
+        ] = {
+          table,
+          variables,
+        };
       },
     },
     states: this.engine.states,