forked from fanruan/fineui
Treecat
2 years ago
17 changed files with 230 additions and 2 deletions
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env node
|
||||
const yargs = require('yargs/yargs'); |
||||
const { hideBin } = require('yargs/helpers'); |
||||
|
||||
const workerCmd = require('./worker/cli.worker'); |
||||
|
||||
const argv = yargs(hideBin(process.argv)).argv; |
||||
|
||||
const cmd = argv._[0]; |
||||
|
||||
const cmds = new Map([ |
||||
['worker', workerCmd], |
||||
]); |
||||
|
||||
if (!cmd) throw new Error('Command is undefined!'); |
||||
|
||||
if (cmds.has(cmd)) { |
||||
cmds.get(cmd)?.exec(argv); |
||||
} else { |
||||
throw new Error(`Command ${cmd} not supported`); |
||||
} |
@ -0,0 +1,76 @@
|
||||
const fs = require('fs'); |
||||
const path = require('path'); |
||||
|
||||
function first2UpperCase(str) { |
||||
return str.toLowerCase().replace(/( |^)[a-z]/g, L => L.toUpperCase()); |
||||
} |
||||
|
||||
function scanAndCreate(structure, workerName, root) { |
||||
Object.keys(structure) |
||||
.forEach(name => { |
||||
if (typeof structure[name] === 'object') { |
||||
fs.mkdirSync(path.resolve(root, name)); |
||||
|
||||
scanAndCreate(structure[name], workerName, path.resolve(root, `./${name}`)); |
||||
} else if (structure[name] === '') { |
||||
fs.appendFileSync(path.resolve(root, name), ''); |
||||
} else if (typeof structure[name] === 'string') { |
||||
let content = fs.readFileSync(structure[name]).toString(); |
||||
|
||||
content = content |
||||
.replace(/\${WorkerName}/g, first2UpperCase(workerName)) |
||||
.replace(/\${workerName}/g, workerName); |
||||
|
||||
fs.appendFileSync(path.resolve(root, name), content); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
module.exports = { |
||||
exec: async args => { |
||||
if (!args.init) { |
||||
throw new Error(`Command init not found in args`); |
||||
} |
||||
|
||||
if (!args.name) { |
||||
throw new Error('Command --name=... not found in args'); |
||||
} |
||||
|
||||
const name = args.name; |
||||
|
||||
const structure = { |
||||
[`${name}_worker`]: { |
||||
'main_thread': { |
||||
action: { |
||||
'action.worker_ability_test.ts': path.resolve(__dirname, './template/main_thread/action/action.worker_ability_test.t'), |
||||
}, |
||||
[`${name}_main_thread.ts`]: path.resolve(__dirname, './template/main_thread/main_thread.t'), |
||||
}, |
||||
utils: { |
||||
'action_type.ts': path.resolve(__dirname, './template/utils/action_type.t'), |
||||
'payload_type.ts': path.resolve(__dirname, './template/utils/payload_type.t'), |
||||
}, |
||||
'worker_thread': { |
||||
action: { |
||||
'action.worker_ability_test.ts': path.resolve(__dirname, './template/worker_thread/action/action.worker_ability_test.t'), |
||||
}, |
||||
[`${name}_worker_thread.ts`]: path.resolve(__dirname, './template/worker_thread/worker_thread.t'), |
||||
}, |
||||
[`${name}_main_thread.helper.ts`]: path.resolve(__dirname, './template/main_thread.helper.t'), |
||||
}, |
||||
}; |
||||
|
||||
scanAndCreate(structure, name, args.where ? path.resolve(args.where) : process.cwd()); |
||||
}, |
||||
}; |
||||
|
||||
// 结构
|
||||
// -xxx_worker
|
||||
// -|--main_thread
|
||||
// -|--|--action
|
||||
// -|--|--xxx_main_thread.ts
|
||||
// -|--utils
|
||||
// -|--|--action_type.ts
|
||||
// -|--worker_thread
|
||||
// -|--|--action
|
||||
// -|--|--worker_main_thread.ts
|
@ -0,0 +1,48 @@
|
||||
import { ${WorkerName}MainThreadWorker } from './main_thread/${workerName}_main_thread'; |
||||
// 不需要一起打包的话则不需要引入这行 |
||||
// FuiWorkerPlugin中的属性会同步到fui-worker中,同时支持loader行内传入属性 |
||||
// 根据实际需求传入inline,返回格式 true -> blob url,false -> servicePath |
||||
import workerUrl from 'fui-worker!./worker_thread/${workerName}_worker_thread'; |
||||
|
||||
export class ${WorkerName}WorkerHelper { |
||||
private worker: ${WorkerName}MainThreadWorker; |
||||
|
||||
/** |
||||
* 拿到helper中的worker |
||||
*/ |
||||
public getWorker() { |
||||
if (this.worker) { |
||||
return this.worker; |
||||
} |
||||
|
||||
this.worker = BI.Workers.createWorker(${WorkerName}MainThreadWorker, { |
||||
workerUrl: this.urlFormatter(workerUrl), |
||||
workerName: BI.UUID(), |
||||
}); |
||||
|
||||
return this.worker; |
||||
} |
||||
|
||||
/** |
||||
* 格式化worker url,比如补充一些环境信息到参数里 |
||||
* 可通过 #hash 将参数传入blob url |
||||
* @param url worker url |
||||
*/ |
||||
private urlFormatter(url: string) { |
||||
return url; |
||||
} |
||||
|
||||
/** |
||||
* 终止worker |
||||
*/ |
||||
public terminate() { |
||||
this.worker?.terminate(); |
||||
} |
||||
} |
||||
|
||||
// 使用示例 |
||||
// const workerHelper = new ${WorkerName}WorkerHelper(); |
||||
|
||||
// workerHelper.getWorker() |
||||
// .testCommunication() |
||||
// .then(res => console.log(res)); |
@ -0,0 +1,13 @@
|
||||
import { WorkerAbilityTestActionType } from '../../utils/action_type'; |
||||
import { WorkerAbilityTestPayload, WorkerAbilityTestReponse } from '../../utils/payload_type'; |
||||
|
||||
export class WorkerAbilityTestMainThreadAction extends BI.Workers.WorkerBaseAction { |
||||
/** |
||||
* 通信能力检测 |
||||
*/ |
||||
public communicationTest(): Promise<WorkerAbilityTestReponse['CommunicationTest']> { |
||||
const mainThreadPostTime: WorkerAbilityTestPayload['CommunicationTest'] = Date.now(); |
||||
|
||||
return this.controller.requestPromise(WorkerAbilityTestActionType.CommunicationTest, mainThreadPostTime); |
||||
} |
||||
} |
@ -0,0 +1,13 @@
|
||||
import { WorkerAbilityTestMainThreadAction } from './action/action.worker_ability_test'; |
||||
|
||||
export class ${WorkerName}MainThreadWorker extends BI.Workers.MainThreadWorker { |
||||
private communicationTest: WorkerAbilityTestMainThreadAction; |
||||
|
||||
public initActions(): void { |
||||
this.communicationTest = this.createAction(WorkerAbilityTestMainThreadAction); |
||||
} |
||||
|
||||
public testCommunication() { |
||||
return this.communicationTest.communicationTest(); |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
/* |
||||
* Worker 事务标识 |
||||
* 每类事务有命名空间, 包含多个具体事务 |
||||
*/ |
||||
|
||||
export const enum WorkerAbilityTestActionType { |
||||
CommunicationTest = 'CommunicationTest', |
||||
} |
@ -0,0 +1,13 @@
|
||||
/** |
||||
* 跨线程通信各事务的发送数据类型声明 |
||||
*/ |
||||
export interface WorkerAbilityTestPayload { |
||||
CommunicationTest: number; |
||||
} |
||||
|
||||
/** |
||||
* 跨线程通信各事务的响应数据类型声明 |
||||
*/ |
||||
export interface WorkerAbilityTestReponse { |
||||
CommunicationTest: number; |
||||
} |
@ -0,0 +1,24 @@
|
||||
import { WorkerAbilityTestActionType } from '../../utils/action_type'; |
||||
import { WorkerAbilityTestPayload, WorkerAbilityTestReponse } from '../../utils/payload_type'; |
||||
|
||||
export class WorkerAbilityTestWorkerThreadAction extends BI.Workers.WorkerBaseAction { |
||||
protected addActionHandler(): void { |
||||
this.controller.addActionHandler( |
||||
WorkerAbilityTestActionType.CommunicationTest, |
||||
this.communicationTest.bind(this) |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* 通信能力检测的处理器 |
||||
*/ |
||||
private communicationTest( |
||||
payload: WorkerAbilityTestPayload['CommunicationTest'] |
||||
): WorkerAbilityTestReponse['CommunicationTest'] { |
||||
const mainThreadPostTime = payload; |
||||
// 收到主线程信息的耗时 |
||||
const workerGetMessageDuration = Date.now() - mainThreadPostTime; |
||||
|
||||
return workerGetMessageDuration; |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
// TODO: 这边需要先import fineui资源 |
||||
import { WorkerAbilityTestWorkerThreadAction } from './action/action.worker_ability_test'; |
||||
|
||||
class ${WorkerName}WorkerTreadWorker extends BI.Workers.WorkerThreadWorker { |
||||
public communicationTest: WorkerAbilityTestWorkerThreadAction; |
||||
|
||||
public initActions(): void { |
||||
this.communicationTest = this.createAction(WorkerAbilityTestWorkerThreadAction); |
||||
} |
||||
} |
||||
|
||||
export const ${workerName}WorkerTreadWorker = BI.Workers.createWorker(${WorkerName}WorkerTreadWorker); |
Loading…
Reference in new issue