template-replacement 3.0.8
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/.workflow/publish_to_npmjs.yml +26 -0
- package/core/base.ts +54 -0
- package/core/general.ts +13 -0
- package/core/sign.ts +13 -0
- package/db/index.ts +5 -0
- package/db/indexedDBCache.ts +129 -0
- package/dispatcher/general.ts +6 -0
- package/dispatcher/sign.ts +6 -0
- package/dispatcher/workerGeneral.ts +7 -0
- package/dispatcher/workerSign.ts +7 -0
- package/dist/assets/template_replacement_core_wasm_bg.wasm +0 -0
- package/dist/assets/template_replacement_sign_core_wasm_bg.wasm +0 -0
- package/dist/base-CC-6cmrq.js +189 -0
- package/dist/general.d.ts +1 -0
- package/dist/index-BkwrGCka.js +61 -0
- package/dist/main/general.js +4543 -0
- package/dist/main/sign.js +4566 -0
- package/dist/replace/general.js +424 -0
- package/dist/replace/sign.js +428 -0
- package/dist/sign.d.ts +1 -0
- package/download/index.ts +22 -0
- package/download/stream.ts +38 -0
- package/helper/index.ts +162 -0
- package/index.ts +21 -0
- package/office/zip.ts +116 -0
- package/package.json +33 -0
- package/replace/base.ts +124 -0
- package/replace/general.ts +14 -0
- package/replace/image.ts +116 -0
- package/replace/interface.ts +29 -0
- package/replace/paramsData.ts +117 -0
- package/replace/sign.ts +31 -0
- package/task/urlDownloadTask.ts +67 -0
- package/temp/index.ts +157 -0
- package/temp/interface.ts +18 -0
- package/tsconfig.json +108 -0
- package/vite.config.ts +36 -0
- package/worker/child/agency.ts +78 -0
- package/worker/child/base.ts +89 -0
- package/worker/child/general.ts +5 -0
- package/worker/child/sign.ts +9 -0
- package/worker/index.ts +65 -0
- package/worker/interface.ts +11 -0
- package/worker/main/general.ts +8 -0
- package/worker/main/index.ts +176 -0
- package/worker/main/sign.ts +8 -0
- package/worker/type.ts +24 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import agency from './agency'
|
|
2
|
+
import { messageData, messageTypes, methodCall } from '../type';
|
|
3
|
+
import ReplaceInterface, { media } from '../../replace/interface';
|
|
4
|
+
import { generateId } from '../../helper';
|
|
5
|
+
import { c } from 'vite/dist/node/types.d-aGj9QkWt';
|
|
6
|
+
|
|
7
|
+
type methodKeys<T> = {
|
|
8
|
+
[K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;
|
|
9
|
+
}[keyof T];
|
|
10
|
+
|
|
11
|
+
const allowCallMethodNames: Partial<Record<methodKeys<ReplaceInterface>, boolean>> = {
|
|
12
|
+
addTempFile: true,
|
|
13
|
+
extractVariables: true,
|
|
14
|
+
extractMedias: true,
|
|
15
|
+
execute: true,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const tasks: Record<string, Function> = {} = {}
|
|
19
|
+
|
|
20
|
+
let dispatch: ReplaceInterface
|
|
21
|
+
|
|
22
|
+
export default function _init(replace: ReplaceInterface) {
|
|
23
|
+
dispatch = new agency(replace)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function call<T>(method: string, ...params: any[]): Promise<T> {
|
|
27
|
+
const replyId = generateId()
|
|
28
|
+
postMessage({
|
|
29
|
+
type: messageTypes.methodCall,
|
|
30
|
+
data: {
|
|
31
|
+
replyId,
|
|
32
|
+
method: method,
|
|
33
|
+
params: params
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
return new Promise<T>((resolve, reject) => {
|
|
38
|
+
tasks[replyId] = resolve
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
addEventListener('message', async event => {
|
|
44
|
+
const data = event.data as messageData
|
|
45
|
+
switch (data.type) {
|
|
46
|
+
case messageTypes.methodCall:
|
|
47
|
+
const callData = data.data as methodCall
|
|
48
|
+
const method = callData.method as methodKeys<ReplaceInterface>
|
|
49
|
+
if (!allowCallMethodNames[method]) {
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
const fun = dispatch[method]
|
|
53
|
+
if (!dispatch[method]) {
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
const res = await Promise.resolve(fun.apply(dispatch, callData.params))
|
|
57
|
+
if (callData.replyId) {
|
|
58
|
+
const transfer: any = []
|
|
59
|
+
if (res) {
|
|
60
|
+
switch (method) {
|
|
61
|
+
case 'execute':
|
|
62
|
+
for (const key in (res as Record<string, Uint8Array>)) {
|
|
63
|
+
const value: Uint8Array = res[key]
|
|
64
|
+
value.buffer && transfer.push(value.buffer)
|
|
65
|
+
}
|
|
66
|
+
break;
|
|
67
|
+
case 'extractMedias':
|
|
68
|
+
for (const key in (res as Record<string, Uint8Array>)) {
|
|
69
|
+
const medias: media[] = res[key]
|
|
70
|
+
medias.forEach(media => {
|
|
71
|
+
transfer.push(media.data.buffer)
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
postMessage({
|
|
77
|
+
type: messageTypes.methodCallReply,
|
|
78
|
+
data: {
|
|
79
|
+
replyId: callData.replyId,
|
|
80
|
+
result: res
|
|
81
|
+
}
|
|
82
|
+
}, { transfer })
|
|
83
|
+
}
|
|
84
|
+
break;
|
|
85
|
+
case messageTypes.methodCallReply:
|
|
86
|
+
tasks[data?.data?.replyId](data?.data?.result)
|
|
87
|
+
delete tasks[data?.data?.replyId]
|
|
88
|
+
}
|
|
89
|
+
})
|
package/worker/index.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { messageData } from "./type"
|
|
2
|
+
import DispatcherInterface from "./interface"
|
|
3
|
+
|
|
4
|
+
export type webworker = new () => Worker
|
|
5
|
+
|
|
6
|
+
export default class worker implements DispatcherInterface {
|
|
7
|
+
#concurrency: number
|
|
8
|
+
#counter: number = 0
|
|
9
|
+
#workers: Worker[] = []
|
|
10
|
+
#listenerList: ((event: MessageEvent)=>void)[] = []
|
|
11
|
+
|
|
12
|
+
constructor(webworker: webworker, concurrency?: number) {
|
|
13
|
+
this.#concurrency = Number(concurrency)
|
|
14
|
+
if (!this.#concurrency || this.#concurrency < 1) {
|
|
15
|
+
try {
|
|
16
|
+
this.#concurrency = navigator.hardwareConcurrency < 8 ? navigator.hardwareConcurrency : 8
|
|
17
|
+
} catch (error) {
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
if (!this.#concurrency || this.#concurrency < 1) {
|
|
21
|
+
this.#concurrency = 1
|
|
22
|
+
}
|
|
23
|
+
for (let index = 0; index < this.#concurrency; index++) {
|
|
24
|
+
this.#addOneWorker(webworker)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
#addOneWorker(webworker: webworker) {
|
|
29
|
+
const worker: Worker = new webworker()
|
|
30
|
+
worker.onmessage = async (event: MessageEvent) => {
|
|
31
|
+
const tasks = []
|
|
32
|
+
for (const fun of this.#listenerList) {
|
|
33
|
+
tasks.push(fun(event))
|
|
34
|
+
}
|
|
35
|
+
(await Promise.all(tasks)).forEach((reply: any)=>{
|
|
36
|
+
reply && worker.postMessage(reply)
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
this.#workers.push(worker)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
concurrency(): number {
|
|
43
|
+
return this.#concurrency
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
postMessage(message: messageData, options?: StructuredSerializeOptions) {
|
|
47
|
+
if (!this.#workers[++this.#counter]) {
|
|
48
|
+
this.#counter = 0
|
|
49
|
+
}
|
|
50
|
+
this.#workers[this.#counter].postMessage(message, options)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
addListener(fun: (event: MessageEvent) => void) {
|
|
54
|
+
this.#listenerList.push(fun)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
removeListener(fun: (event: MessageEvent) => void) {
|
|
58
|
+
for (const i in this.#listenerList) {
|
|
59
|
+
if (this.#listenerList[i] == fun) {
|
|
60
|
+
this.#listenerList.splice((i as unknown) as number, 1)
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { messageData, methodCall } from "./type";
|
|
2
|
+
|
|
3
|
+
export default interface DispatcherInterface {
|
|
4
|
+
concurrency(): number
|
|
5
|
+
|
|
6
|
+
postMessage(message: messageData|methodCall, options?: StructuredSerializeOptions): void
|
|
7
|
+
|
|
8
|
+
addListener(fun: (event: MessageEvent) => void): void
|
|
9
|
+
|
|
10
|
+
removeListener(fun: (event: MessageEvent) => void): void
|
|
11
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { messageData, messageTypes, methodCall, methodCallReply } from '../type';
|
|
2
|
+
import DispatcherInterface from '../interface';
|
|
3
|
+
import { generateId, splitArrayIntoChunks } from '../../helper';
|
|
4
|
+
import ReplaceInterface, { media } from '../../replace/interface';
|
|
5
|
+
import paramsData from '../../replace/paramsData';
|
|
6
|
+
import Temp, { transmitFileInfo } from '../../temp';
|
|
7
|
+
|
|
8
|
+
type methodKeys<T> = {
|
|
9
|
+
[K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;
|
|
10
|
+
}[keyof T];
|
|
11
|
+
|
|
12
|
+
const allowCallMethodNames: Partial<Record<methodKeys<ReplaceInterface>, boolean>> = {
|
|
13
|
+
sign: true,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// 分片最小任务数量
|
|
17
|
+
const chunkMinNum = 20
|
|
18
|
+
|
|
19
|
+
export default class WorkerReplace implements ReplaceInterface{
|
|
20
|
+
#files: Temp[] = []
|
|
21
|
+
#dispatcher: DispatcherInterface
|
|
22
|
+
#tasks: Record<string, Function> = {}
|
|
23
|
+
#concurrency: number = 1
|
|
24
|
+
|
|
25
|
+
constructor(dispatcher: DispatcherInterface) {
|
|
26
|
+
this.#dispatcher = dispatcher
|
|
27
|
+
this.setDispatcher(dispatcher)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
setDispatcher(dispatcher: DispatcherInterface) {
|
|
31
|
+
dispatcher.addListener(event => {
|
|
32
|
+
const data = event.data as messageData
|
|
33
|
+
switch (data.type) {
|
|
34
|
+
case messageTypes.methodCallReply:
|
|
35
|
+
const replyData = data.data as methodCallReply
|
|
36
|
+
if (!replyData) {
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
if (this.#tasks[replyData.replyId]) {
|
|
40
|
+
this.#tasks[replyData.replyId](replyData.result)
|
|
41
|
+
delete this.#tasks[replyData.replyId]
|
|
42
|
+
}
|
|
43
|
+
break;
|
|
44
|
+
case messageTypes.methodCall:
|
|
45
|
+
const callData = data.data as methodCall
|
|
46
|
+
const method = callData.method as methodKeys<ReplaceInterface>
|
|
47
|
+
if (!allowCallMethodNames[method]) {
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
const fun = this[method]
|
|
51
|
+
if (!fun) {
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
const callRes = fun.apply(this, callData.params)
|
|
55
|
+
if (!callData.replyId) {
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
return new Promise(async (resolve, reject) => {
|
|
59
|
+
resolve({
|
|
60
|
+
type: messageTypes.methodCallReply,
|
|
61
|
+
data: {
|
|
62
|
+
replyId: callData.replyId,
|
|
63
|
+
result: await Promise.resolve(callRes)
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
this.#dispatcher = dispatcher
|
|
71
|
+
this.#concurrency = this.#dispatcher.concurrency()
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
#call(method: string, params: any[]): any {
|
|
75
|
+
const transfer: any = []
|
|
76
|
+
|
|
77
|
+
params.forEach(param => {
|
|
78
|
+
if (param instanceof Array) {
|
|
79
|
+
param.forEach(item => {
|
|
80
|
+
if (item?.uint8Array?.buffer?.length) {
|
|
81
|
+
transfer.push(item.uint8Array.buffer)
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
const replyId = generateId()
|
|
88
|
+
this.#dispatcher.postMessage({
|
|
89
|
+
type: messageTypes.methodCall,
|
|
90
|
+
data: {
|
|
91
|
+
replyId,
|
|
92
|
+
method,
|
|
93
|
+
params
|
|
94
|
+
}
|
|
95
|
+
}, { transfer })
|
|
96
|
+
return new Promise((resolve, reject) => {
|
|
97
|
+
this.#tasks[replyId] = resolve
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
//分片
|
|
102
|
+
#chunk<T>(files: T[], chunkPackage?: (chunkData:T[]) => any): any[] {
|
|
103
|
+
let chunks = []
|
|
104
|
+
if (this.#concurrency > 1 && files.length > chunkMinNum) {
|
|
105
|
+
const chunkSize = Math.ceil(files.length/(Math.round(files.length/chunkMinNum)))
|
|
106
|
+
chunks = splitArrayIntoChunks(files, chunkSize)
|
|
107
|
+
}else {
|
|
108
|
+
chunks = [files]
|
|
109
|
+
}
|
|
110
|
+
if (chunkPackage) {
|
|
111
|
+
for (const i in chunks) {
|
|
112
|
+
chunks[i] = chunkPackage(chunks[i])
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return chunks
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async #getTempFileData(files: Temp[] | undefined): Promise<transmitFileInfo[]> {
|
|
119
|
+
if (!files) {
|
|
120
|
+
files = this.#files
|
|
121
|
+
}
|
|
122
|
+
const tasks: Promise<transmitFileInfo|undefined>[] = []
|
|
123
|
+
files.forEach(file => {
|
|
124
|
+
tasks.push(file.getTransmitFileInfo())
|
|
125
|
+
})
|
|
126
|
+
const res = await Promise.all(tasks)
|
|
127
|
+
return res.filter(item => !!item)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
addTempFile(tempFile: Temp): void {
|
|
131
|
+
this.#files.push(tempFile)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
clear(): void {
|
|
135
|
+
this.#files.length = 0
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async #chunkCall(method: string, paramChunks: any[]): Promise<Record<string, any>>{
|
|
139
|
+
const tasks: Promise<Record<string, any>>[] = []
|
|
140
|
+
paramChunks.forEach(chunk => {
|
|
141
|
+
tasks.push(this.#call(method, chunk))
|
|
142
|
+
})
|
|
143
|
+
const tasksRes = await Promise.all(tasks)
|
|
144
|
+
return tasksRes.reduce((accumulator, current) => {
|
|
145
|
+
return {...accumulator, ...current}
|
|
146
|
+
}, {})
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async extractVariables(files: Temp[] | undefined): Promise<Record<string, string[]>> {
|
|
150
|
+
const fileData = await this.#getTempFileData(files)
|
|
151
|
+
const chunks = this.#chunk(fileData, chunkData => {
|
|
152
|
+
return [chunkData]
|
|
153
|
+
})
|
|
154
|
+
return this.#chunkCall('extractVariables', chunks)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async extractMedias(files: Temp[] | undefined): Promise<Record<string, media[]>> {
|
|
158
|
+
const fileData = await this.#getTempFileData(files)
|
|
159
|
+
const chunks = this.#chunk(fileData, chunkData => {
|
|
160
|
+
return [chunkData]
|
|
161
|
+
})
|
|
162
|
+
return this.#chunkCall('extractMedias', chunks)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async sign(data: any): Promise<string> {
|
|
166
|
+
return ''
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async execute(params: paramsData, files: Temp[] | undefined): Promise<Record<string, Uint8Array>> {
|
|
170
|
+
const fileData = await this.#getTempFileData(files)
|
|
171
|
+
const chunks = this.#chunk(fileData, chunkData => {
|
|
172
|
+
return [params, chunkData]
|
|
173
|
+
})
|
|
174
|
+
return this.#chunkCall('execute', chunks)
|
|
175
|
+
}
|
|
176
|
+
}
|
package/worker/type.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export enum messageTypes {
|
|
2
|
+
replace,
|
|
3
|
+
replaceProgress,
|
|
4
|
+
sign,
|
|
5
|
+
signReply,
|
|
6
|
+
methodCall,
|
|
7
|
+
methodCallReply,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type messageData = {
|
|
11
|
+
type: messageTypes,
|
|
12
|
+
data: any | methodCall | methodCallReply
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type methodCall = {
|
|
16
|
+
replyId?: string,
|
|
17
|
+
method: string,
|
|
18
|
+
params: any[]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type methodCallReply = {
|
|
22
|
+
replyId: string,
|
|
23
|
+
result: any
|
|
24
|
+
}
|