Sfoglia il codice sorgente

feature: 多线程

xiongxt 1 anno fa
parent
commit
643604c4f3

+ 1 - 0
dist/css/thread.956728ca.css

@@ -0,0 +1 @@
+h3[data-v-1a0c8e80]{font-size:.17143rem;padding-bottom:.14286rem;border-bottom:.00714rem solid #eee;margin-bottom:.14286rem}.desc[data-v-1a0c8e80]{color:#666}div[data-v-1a0c8e80]{margin:.14286rem 0}

+ 1 - 1
dist/index.html

@@ -1 +1 @@
-<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/ludash/favicon.ico"><title>ludash</title><script defer="defer" src="/ludash/js/chunk-vendors.8715a4be.js"></script><script defer="defer" src="/ludash/js/app.9be6db5d.js"></script><link href="/ludash/css/app.414ee198.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but ludash doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
+<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/ludash/favicon.ico"><title>ludash</title><script defer="defer" src="/ludash/js/chunk-vendors.8715a4be.js"></script><script defer="defer" src="/ludash/js/app.5ee35f39.js"></script><link href="/ludash/css/app.414ee198.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but ludash doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>

File diff suppressed because it is too large
+ 0 - 0
dist/js/app.5ee35f39.js


File diff suppressed because it is too large
+ 0 - 0
dist/js/app.5ee35f39.js.map


File diff suppressed because it is too large
+ 0 - 0
dist/js/app.9be6db5d.js


File diff suppressed because it is too large
+ 0 - 0
dist/js/app.9be6db5d.js.map


+ 2 - 2
dist/js/formula.40fae326.js → dist/js/formula.c37d7fda.js

@@ -1,2 +1,2 @@
-"use strict";(self["webpackChunkludash"]=self["webpackChunkludash"]||[]).push([[183],{8061:function(n,l,e){e.r(l),e.d(l,{default:function(){return f}});var u=e(3396),o=e(4870),a=e(6351),s=e(5017),t=e(9908);const c=(0,u._)("p",{class:"demo"},"DEMO",-1);var r={__name:"formula",setup(n){function l(){const n=new t.Si("(a[0]+b.x)/c");console.log(n.result({a:[3],b:{x:9},c:9})),n.destroy()}const e=(0,o.iH)('import { Formula } from "ludash";\nconst f = new Formula("(a[0]+b.x)/c");\nconsole.log(\n  f.result({\n    a: [3],\n    b: { x: 9 },\n    c: 9,\n  })\n);\nf.destroy();');return(n,t)=>((0,u.wg)(),(0,u.iD)("div",null,[(0,u.Wm)(a.Z,{title:"formula",desc:"手动运行字符串公式"},{default:(0,u.w5)((()=>[(0,u._)("p",{class:"run"},[(0,u._)("button",{onClick:l},"运行"),(0,u.Uk)("请在控制台查看结果 ")]),c,(0,u.Wm)((0,o.SU)(s.Z1),{modelValue:e.value,"onUpdate:modelValue":t[0]||(t[0]=n=>e.value=n),disabled:!0},null,8,["modelValue"])])),_:1})]))}};const d=r;var f=d}}]);
-//# sourceMappingURL=formula.40fae326.js.map
+"use strict";(self["webpackChunkludash"]=self["webpackChunkludash"]||[]).push([[183],{8061:function(n,l,e){e.r(l),e.d(l,{default:function(){return f}});var u=e(3396),o=e(4870),a=e(6351),s=e(5017),t=e(8822);const c=(0,u._)("p",{class:"demo"},"DEMO",-1);var r={__name:"formula",setup(n){function l(){const n=new t.Si("(a[0]+b.x)/c");console.log(n.result({a:[3],b:{x:9},c:9})),n.destroy()}const e=(0,o.iH)('import { Formula } from "ludash";\nconst f = new Formula("(a[0]+b.x)/c");\nconsole.log(\n  f.result({\n    a: [3],\n    b: { x: 9 },\n    c: 9,\n  })\n);\nf.destroy();');return(n,t)=>((0,u.wg)(),(0,u.iD)("div",null,[(0,u.Wm)(a.Z,{title:"formula",desc:"手动运行字符串公式"},{default:(0,u.w5)((()=>[(0,u._)("p",{class:"run"},[(0,u._)("button",{onClick:l},"运行"),(0,u.Uk)("请在控制台查看结果 ")]),c,(0,u.Wm)((0,o.SU)(s.Z1),{modelValue:e.value,"onUpdate:modelValue":t[0]||(t[0]=n=>e.value=n),disabled:!0},null,8,["modelValue"])])),_:1})]))}};const d=r;var f=d}}]);
+//# sourceMappingURL=formula.c37d7fda.js.map

+ 1 - 1
dist/js/formula.40fae326.js.map → dist/js/formula.c37d7fda.js.map

@@ -1 +1 @@
-{"version":3,"file":"js/formula.40fae326.js","mappings":"6RAmBA,SAASA,IACP,MAAMC,EAAI,IAAIC,EAAAA,GAAQ,gBACtBC,QAAQC,IACNH,EAAEI,OAAO,CACPC,EAAG,CAAC,GACJC,EAAG,CAAEC,EAAG,GACRC,EAAG,KAGPR,EAAES,SACJ,CAEA,MAAMC,GAAOC,EAAAA,EAAAA,IAAK,2K,6VC5BlB,MAAMC,EAAc,EAEpB,O","sources":["webpack://ludash/./src/views/formula.vue","webpack://ludash/./src/views/formula.vue?3fb1"],"sourcesContent":["<template>\r\n  <div>\r\n    <Block title=\"formula\" desc=\"手动运行字符串公式\">\r\n      <p class=\"run\">\r\n        <button @click=\"execute\">运行</button>请在控制台查看结果\r\n      </p>\r\n      <p class=\"demo\">DEMO</p>\r\n      <Codemirror v-model=\"code\" :disabled=\"true\" />\r\n    </Block>\r\n  </div>\r\n</template>\r\n\r\n<script setup>\r\nimport Block from \"@/components/block.vue\";\r\nimport { ref } from \"vue\";\r\nimport { Codemirror } from \"vue-codemirror\";\r\n\r\nimport { Formula } from \"../../lib\";\r\n\r\nfunction execute() {\r\n  const f = new Formula(\"(a[0]+b.x)/c\");\r\n  console.log(\r\n    f.result({\r\n      a: [3],\r\n      b: { x: 9 },\r\n      c: 9,\r\n    })\r\n  );\r\n  f.destroy();\r\n}\r\n\r\nconst code = ref(`import { Formula } from \"ludash\";\r\nconst f = new Formula(\"(a[0]+b.x)/c\");\r\nconsole.log(\r\n  f.result({\r\n    a: [3],\r\n    b: { x: 9 },\r\n    c: 9,\r\n  })\r\n);\r\nf.destroy();`);\r\n</script>\r\n","import script from \"./formula.vue?vue&type=script&setup=true&lang=js\"\nexport * from \"./formula.vue?vue&type=script&setup=true&lang=js\"\n\nconst __exports__ = script;\n\nexport default __exports__"],"names":["execute","f","Formula","console","log","result","a","b","x","c","destroy","code","ref","__exports__"],"sourceRoot":""}
+{"version":3,"file":"js/formula.c37d7fda.js","mappings":"6RAmBA,SAASA,IACP,MAAMC,EAAI,IAAIC,EAAAA,GAAQ,gBACtBC,QAAQC,IACNH,EAAEI,OAAO,CACPC,EAAG,CAAC,GACJC,EAAG,CAAEC,EAAG,GACRC,EAAG,KAGPR,EAAES,SACJ,CAEA,MAAMC,GAAOC,EAAAA,EAAAA,IAAK,2K,6VC5BlB,MAAMC,EAAc,EAEpB,O","sources":["webpack://ludash/./src/views/formula.vue","webpack://ludash/./src/views/formula.vue?3fb1"],"sourcesContent":["<template>\r\n  <div>\r\n    <Block title=\"formula\" desc=\"手动运行字符串公式\">\r\n      <p class=\"run\">\r\n        <button @click=\"execute\">运行</button>请在控制台查看结果\r\n      </p>\r\n      <p class=\"demo\">DEMO</p>\r\n      <Codemirror v-model=\"code\" :disabled=\"true\" />\r\n    </Block>\r\n  </div>\r\n</template>\r\n\r\n<script setup>\r\nimport Block from \"@/components/block.vue\";\r\nimport { ref } from \"vue\";\r\nimport { Codemirror } from \"vue-codemirror\";\r\n\r\nimport { Formula } from \"../../lib\";\r\n\r\nfunction execute() {\r\n  const f = new Formula(\"(a[0]+b.x)/c\");\r\n  console.log(\r\n    f.result({\r\n      a: [3],\r\n      b: { x: 9 },\r\n      c: 9,\r\n    })\r\n  );\r\n  f.destroy();\r\n}\r\n\r\nconst code = ref(`import { Formula } from \"ludash\";\r\nconst f = new Formula(\"(a[0]+b.x)/c\");\r\nconsole.log(\r\n  f.result({\r\n    a: [3],\r\n    b: { x: 9 },\r\n    c: 9,\r\n  })\r\n);\r\nf.destroy();`);\r\n</script>\r\n","import script from \"./formula.vue?vue&type=script&setup=true&lang=js\"\nexport * from \"./formula.vue?vue&type=script&setup=true&lang=js\"\n\nconst __exports__ = script;\n\nexport default __exports__"],"names":["execute","f","Formula","console","log","result","a","b","x","c","destroy","code","ref","__exports__"],"sourceRoot":""}

+ 2 - 0
dist/js/thread.052acdfd.js

@@ -0,0 +1,2 @@
+"use strict";(self["webpackChunkludash"]=self["webpackChunkludash"]||[]).push([[834],{3092:function(n,e,t){t.r(e),t.d(e,{default:function(){return f}});var r=t(3396),u=t(4870),i=t(6351),l=t(5017),a=t(8822);const o=(0,r._)("span",{id:"t1",style:{"padding-right":"10px"}},null,-1),d=(0,r._)("span",{id:"t2"},null,-1),s=(0,r._)("p",{class:"demo"},"DEMO",-1);var c={__name:"thread",setup(n){let e=0,t=0,c=!1;function p(){console.log(a.jz),c=!1,a.jz.create((n=>{if(document.querySelector("#t1").innerHTML=e++,!c)return{n1:e}}),{},{priority:10}),a.jz.create((n=>{if(document.querySelector("#t2").innerHTML=t++,!c)return{n2:t}}),{},{priority:10}).start(),window.Thread=a.jz}function f(){c=!0}const h=(0,u.iH)('import { Thread } from "ludash";\nThread.create(\n    (taskUnit) => { // 线程运行主函数体\n      document.querySelector("#t1").innerHTML = n1++;\n      if (shouldStop) {\n        return undefined;\n      }\n      return { n1 };  // taskUnit 下一次执行时的参数  返回undefined则线程停止自动销毁\n    },\n    {}, // 第一次运行时的taskUnit\n    { priority: 10 } // priority 是优先级,数字越大优先级越高,程序会优先将优先级高的线程运行结束\n  ).start()');return(n,e)=>((0,r.wg)(),(0,r.iD)("div",null,[(0,r.Wm)(i.Z,{title:"thread",desc:"前端模拟多线程,跑大任务时不会阻塞主线程"},{default:(0,r.w5)((()=>[(0,r._)("p",{class:"run"},[o,d,(0,r._)("button",{onClick:p},"运行"),(0,r._)("button",{onClick:f},"stop"),(0,r.Uk)("请在控制台查看结果 ")]),s,(0,r.Wm)((0,u.SU)(l.Z1),{modelValue:h.value,"onUpdate:modelValue":e[0]||(e[0]=n=>h.value=n),disabled:!0},null,8,["modelValue"])])),_:1})]))}};const p=c;var f=p}}]);
+//# sourceMappingURL=thread.052acdfd.js.map

File diff suppressed because it is too large
+ 0 - 0
dist/js/thread.052acdfd.js.map


+ 21 - 0
lib/async.js

@@ -34,3 +34,24 @@ export function nextTick(time = 0) {
         }, time);
     });
 }
+export function objectForEach(obj, callback) {
+    const keys = Reflect.ownKeys(obj);
+    keys.forEach((key) => {
+        callback(Reflect.get(obj, key), key);
+    });
+}
+export function asyncObjectForEach(obj, callback) {
+    return __awaiter(this, void 0, void 0, function* () {
+        const keys = Reflect.ownKeys(obj);
+        let index = 0;
+        const newCallback = () => __awaiter(this, void 0, void 0, function* () {
+            const key = keys[index];
+            const res = yield callback(Reflect.get(obj, key), key);
+            if (index < keys.length - 1 && res !== false) {
+                index++;
+                yield newCallback();
+            }
+        });
+        return yield newCallback();
+    });
+}

+ 1 - 0
lib/index.js

@@ -4,3 +4,4 @@ export * from "./storage";
 export * from "./flexible";
 export * from "./http";
 export * from "./formula";
+export * from "./thread";

+ 111 - 0
lib/thread.js

@@ -0,0 +1,111 @@
+let isLooping = false;
+function getMapKeys(map) {
+    return Array.from(map).map((it) => it[0]);
+}
+function workLoop() {
+    isLooping = true;
+    const prioritys = getMapKeys(Thread.threadMap).sort((a, b) => b - a);
+    const curPriority = prioritys[0];
+    const curPriorityArray = Thread.threadMap.get(curPriority);
+    curPriorityArray.forEach((thread) => {
+        thread.samePriorityLength = curPriorityArray.length;
+        let taskUnit = thread.taskUnit;
+        thread.start();
+        while (taskUnit && !thread.shouldYield && !thread.isEmpty) {
+            taskUnit = thread.taskUnit = thread.exec();
+        }
+        if (taskUnit === undefined) {
+            thread.destroy();
+        }
+        else {
+            thread.pause();
+        }
+        thread.pause();
+    });
+    if (Thread.isAllEmpty()) {
+        isLooping = false;
+    }
+    else {
+        nextTick(workLoop);
+    }
+}
+let channel;
+function nextTick(callback) {
+    if (window.MessageChannel) {
+        if (!channel) {
+            channel = new MessageChannel();
+            channel.port1.onmessage = callback;
+        }
+        channel.port2.postMessage("notify");
+    }
+    else {
+        setTimeout(callback, 0);
+    }
+}
+class Thread {
+    static create(runner, taskUnit = undefined, options) {
+        const thread = new Thread(runner, taskUnit, options);
+        Thread.threads.push(thread);
+        const newThreadPriority = thread.options.priority;
+        const curPriorityArray = Thread.threadMap.get(newThreadPriority);
+        if (curPriorityArray) {
+            curPriorityArray.push(thread);
+        }
+        else {
+            Thread.threadMap.set(newThreadPriority, [thread]);
+        }
+        return thread;
+    }
+    static isAllEmpty() {
+        return !Thread.threads.find((thread) => !thread.isEmpty);
+    }
+    constructor(runner, taskUnit, options) {
+        this.runner = undefined;
+        this.taskUnit = undefined;
+        this.options = {
+            priority: 0,
+        };
+        this.status = "normal";
+        this.samePriorityLength = 0;
+        this.startTime = 0;
+        this.runner = runner;
+        this.taskUnit = taskUnit;
+        this.options = Object.assign(this.options, options);
+    }
+    start() {
+        this.startTime = Date.now();
+        if (!isLooping) {
+            workLoop();
+        }
+    }
+    pause() {
+        this.startTime = 0;
+    }
+    exec() {
+        return this.runner(this.taskUnit);
+    }
+    destroy() {
+        Thread.threads.splice(Thread.threads.findIndex((it) => it === this), 1);
+        const curPriorityArray = Thread.threadMap.get(this.options.priority);
+        curPriorityArray.splice(curPriorityArray.findIndex((it) => it === this), 1);
+        if (curPriorityArray.length === 0) {
+            Thread.threadMap.delete(this.options.priority);
+        }
+        this.runner = undefined;
+        this.options = undefined;
+        this.taskUnit = undefined;
+    }
+    get shouldYield() {
+        return Date.now() > this.startTime + this.yieldInterval;
+    }
+    get isEmpty() {
+        return this.taskUnit === undefined;
+    }
+    get yieldInterval() {
+        return Thread.yieldInterval / this.samePriorityLength;
+    }
+}
+Thread.threads = [];
+Thread.threadMap = new Map();
+Thread.yieldInterval = 5;
+export { Thread };

+ 1 - 0
lib/unitOfWork.js

@@ -0,0 +1 @@
+function loop() { }

+ 1 - 0
sdk/index.ts

@@ -4,3 +4,4 @@ export * from "./storage";
 export * from "./flexible";
 export * from "./http";
 export * from "./formula";
+export * from "./thread";

+ 140 - 0
sdk/thread.ts

@@ -0,0 +1,140 @@
+type Runner<T = unknown> = ((taskUnit: T) => T | undefined) | undefined;
+type ThreadOptions = { priority: number };
+
+let isLooping = false;
+
+function getMapKeys<K extends number | string | symbol>(map: Map<K, unknown>) {
+  return Array.from(map).map((it) => it[0]);
+}
+
+function workLoop() {
+  isLooping = true;
+
+  const prioritys = getMapKeys(Thread.threadMap).sort((a, b) => b - a);
+  const curPriority = prioritys[0];
+
+  const curPriorityArray = Thread.threadMap.get(curPriority);
+  curPriorityArray.forEach((thread) => {
+    thread.samePriorityLength = curPriorityArray.length;
+    let taskUnit = thread.taskUnit;
+    thread.start();
+    while (taskUnit && !thread.shouldYield && !thread.isEmpty) {
+      taskUnit = thread.taskUnit = thread.exec();
+    }
+    if (taskUnit === undefined) {
+      thread.destroy();
+    } else {
+      thread.pause();
+    }
+    thread.pause();
+  });
+  if (Thread.isAllEmpty()) {
+    isLooping = false;
+  } else {
+    nextTick(workLoop);
+  }
+}
+
+let channel: MessageChannel;
+function nextTick(callback) {
+  if (window.MessageChannel) {
+    if (!channel) {
+      channel = new MessageChannel();
+      channel.port1.onmessage = callback;
+    }
+    channel.port2.postMessage("notify");
+  } else {
+    setTimeout(callback, 0);
+  }
+}
+
+class Thread {
+  static create(
+    runner: Runner,
+    taskUnit: unknown = undefined,
+    options: ThreadOptions
+  ) {
+    const thread = new Thread(runner, taskUnit, options);
+    Thread.threads.push(thread);
+    const newThreadPriority = thread.options.priority;
+    const curPriorityArray: Thread[] | undefined =
+      Thread.threadMap.get(newThreadPriority);
+    if (curPriorityArray) {
+      curPriorityArray.push(thread);
+    } else {
+      Thread.threadMap.set(newThreadPriority, [thread]);
+    }
+    return thread;
+  }
+
+  static threads: Thread[] = [];
+  static threadMap: Map<number, Thread[]> = new Map();
+
+  static isAllEmpty() {
+    return !Thread.threads.find((thread) => !thread.isEmpty);
+  }
+
+  static yieldInterval = 5;
+
+  runner: Runner = undefined;
+  taskUnit: unknown = undefined;
+  options: ThreadOptions = {
+    priority: 0,
+  };
+  status: "normal" | "destroyed" = "normal";
+  samePriorityLength = 0;
+  private startTime = 0;
+
+  constructor(runner: Runner, taskUnit: unknown, options: ThreadOptions) {
+    this.runner = runner;
+    this.taskUnit = taskUnit;
+    this.options = Object.assign(this.options, options);
+  }
+
+  start() {
+    this.startTime = Date.now();
+    if (!isLooping) {
+      workLoop();
+    }
+  }
+
+  pause() {
+    this.startTime = 0;
+  }
+
+  exec() {
+    return this.runner(this.taskUnit);
+  }
+
+  destroy() {
+    Thread.threads.splice(
+      Thread.threads.findIndex((it) => it === this),
+      1
+    );
+    const curPriorityArray = Thread.threadMap.get(this.options.priority);
+    curPriorityArray.splice(
+      curPriorityArray.findIndex((it) => it === this),
+      1
+    );
+    if (curPriorityArray.length === 0) {
+      Thread.threadMap.delete(this.options.priority);
+    }
+    this.runner = undefined;
+    this.options = undefined;
+    this.taskUnit = undefined;
+  }
+
+  get shouldYield() {
+    return Date.now() > this.startTime + this.yieldInterval;
+  }
+
+  get isEmpty() {
+    return this.taskUnit === undefined;
+  }
+
+  get yieldInterval() {
+    return Thread.yieldInterval / this.samePriorityLength;
+  }
+}
+
+export { Thread };

+ 6 - 0
src/router/index.js

@@ -76,6 +76,12 @@ const routes = [
         component: () =>
           import(/* webpackChunkName: "formula" */ "../views/formula.vue"),
       },
+      {
+        path: "thread",
+        name: "thread",
+        component: () =>
+          import(/* webpackChunkName: "thread" */ "../views/thread.vue"),
+      },
       {
         path: "",
         redirect: {

+ 72 - 0
src/views/thread.vue

@@ -0,0 +1,72 @@
+<template>
+  <div>
+    <Block title="thread" desc="前端模拟多线程,跑大任务时不会阻塞主线程">
+      <p class="run">
+        <span id="t1" style="padding-right: 10px"></span>
+        <span id="t2"></span>
+        <button @click="execute">运行</button
+        ><button @click="stop">stop</button>请在控制台查看结果
+      </p>
+      <p class="demo">DEMO</p>
+      <Codemirror v-model="code" :disabled="true" />
+    </Block>
+  </div>
+</template>
+
+<script setup>
+import Block from "@/components/block.vue";
+import { ref } from "vue";
+import { Codemirror } from "vue-codemirror";
+
+import { Thread } from "../../lib";
+
+let n1 = 0,
+  n2 = 0,
+  shouldStop = false;
+function execute() {
+  console.log(Thread);
+  shouldStop = false;
+  Thread.create(
+    (unit) => {
+      document.querySelector("#t1").innerHTML = n1++;
+      if (shouldStop) {
+        return undefined;
+      }
+      return { n1 };
+    },
+    {},
+    { priority: 10 }
+  );
+  Thread.create(
+    (unit) => {
+      document.querySelector("#t2").innerHTML = n2++;
+      if (shouldStop) {
+        return undefined;
+      }
+      return { n2 };
+    },
+    {},
+    {
+      priority: 10,
+    }
+  ).start();
+  window.Thread = Thread;
+}
+
+function stop() {
+  shouldStop = true;
+}
+
+const code = ref(`import { Thread } from "ludash";
+Thread.create(
+    (taskUnit) => { // 线程运行主函数体
+      document.querySelector("#t1").innerHTML = n1++;
+      if (shouldStop) {
+        return undefined;
+      }
+      return { n1 };  // taskUnit 下一次执行时的参数  返回undefined则线程停止自动销毁
+    },
+    {}, // 第一次运行时的taskUnit
+    { priority: 10 } // priority 是优先级,数字越大优先级越高,程序会优先将优先级高的线程运行结束
+  ).start()`); // 启动运行
+</script>

+ 2 - 0
types/async.d.ts

@@ -1,3 +1,5 @@
 export declare function asyncWhile(checker: (index: number) => boolean | Promise<boolean>, callback: (index: number) => void | Promise<void>): Promise<void>;
 export declare function asyncForEach<T = any>(array: T[], callback: (item: T, index: number) => boolean | Promise<boolean>): Promise<void>;
 export declare function nextTick(time?: number): Promise<unknown>;
+export declare function objectForEach<O extends Record<PropertyKey, unknown>>(obj: O, callback: (value: O[keyof O], key: PropertyKey) => void): void;
+export declare function asyncObjectForEach<O extends Record<PropertyKey, unknown>>(obj: O, callback: (value: O[keyof O], key: PropertyKey) => boolean | Promise<boolean>): Promise<void>;

+ 1 - 0
types/index.d.ts

@@ -4,3 +4,4 @@ export * from "./storage";
 export * from "./flexible";
 export * from "./http";
 export * from "./formula";
+export * from "./thread";

+ 26 - 0
types/thread.d.ts

@@ -0,0 +1,26 @@
+type Runner<T = unknown> = ((taskUnit: T) => T | undefined) | undefined;
+type ThreadOptions = {
+    priority: number;
+};
+declare class Thread {
+    static create(runner: Runner, taskUnit: unknown, options: ThreadOptions): Thread;
+    static threads: Thread[];
+    static threadMap: Map<number, Thread[]>;
+    static isAllEmpty(): boolean;
+    static yieldInterval: number;
+    runner: Runner;
+    taskUnit: unknown;
+    options: ThreadOptions;
+    status: "normal" | "destroyed";
+    samePriorityLength: number;
+    private startTime;
+    constructor(runner: Runner, taskUnit: unknown, options: ThreadOptions);
+    start(): void;
+    pause(): void;
+    exec(): unknown;
+    destroy(): void;
+    get shouldYield(): boolean;
+    get isEmpty(): boolean;
+    get yieldInterval(): number;
+}
+export { Thread };

+ 1 - 0
types/unitOfWork.d.ts

@@ -0,0 +1 @@
+declare function loop(): void;

Some files were not shown because too many files changed in this diff