template-replacement 3.3.2 → 3.4.0
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/.editorconfig +8 -0
- package/.oxfmtrc.jsonc +7 -0
- package/.oxlintrc.json +3 -0
- package/README.md +39 -9
- package/core/base.ts +54 -55
- package/core/general.ts +37 -9
- package/core/sign.ts +43 -8
- package/dispatcher/general.ts +2 -1
- package/dispatcher/sign.ts +2 -1
- package/dispatcher/workerGeneral.ts +1 -1
- package/dispatcher/workerSign.ts +1 -1
- package/dist/base-DQz39fXI.js +249 -0
- package/dist/index-oILo_kXG.js +46 -0
- package/dist/main/general.js +1373 -1401
- package/dist/main/sign.js +1559 -1573
- package/dist/replace/general.js +281 -306
- package/dist/replace/sign.js +304 -315
- package/download/index.ts +13 -13
- package/download/stream.ts +29 -28
- package/eslint.config.ts +28 -0
- package/fileSystem/db/index.ts +25 -25
- package/fileSystem/db/indexedDBCache.ts +142 -124
- package/fileSystem/index.ts +5 -8
- package/fileSystem/interface.ts +4 -5
- package/fileSystem/opfs/index.ts +40 -36
- package/helper/index.ts +144 -116
- package/index.ts +9 -17
- package/office/zip.ts +106 -97
- package/package.json +17 -11
- package/replace/base.ts +203 -214
- package/replace/general.ts +44 -19
- package/replace/image.ts +88 -86
- package/replace/interface.ts +29 -24
- package/replace/paramsData.ts +108 -96
- package/replace/sign.ts +79 -43
- package/task/urlDownloadTask.ts +54 -63
- package/temp/index.ts +139 -131
- package/temp/interface.ts +8 -8
- package/tsconfig.json +1 -1
- package/vite.config.ts +11 -14
- package/worker/child/agency.ts +49 -41
- package/worker/child/base.ts +125 -89
- package/worker/child/general.ts +2 -3
- package/worker/child/sign.ts +4 -4
- package/worker/index.ts +52 -51
- package/worker/interface.ts +9 -6
- package/worker/main/general.ts +5 -5
- package/worker/main/index.ts +191 -66
- package/worker/main/sign.ts +5 -5
- package/worker/type.ts +16 -15
- 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-BuKBOMgk.js +0 -269
- package/dist/general.d.ts +0 -1
- package/dist/index-tFDVIkZX.js +0 -46
- package/dist/sign.d.ts +0 -1
package/worker/main/index.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
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'
|
|
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
|
+
import { Zip, ZipDeflate } from 'fflate'
|
|
7
8
|
|
|
8
9
|
type methodKeys<T> = {
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
11
|
+
[K in keyof T]: T[K] extends Function ? K : never
|
|
12
|
+
}[keyof T]
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
type allMethodNames = methodKeys<ReplaceInterface>
|
|
15
|
+
|
|
16
|
+
const allowCallMethodNames: Set<allMethodNames> = new Set(["sign"])
|
|
15
17
|
|
|
16
18
|
// 分片最小任务数量
|
|
17
19
|
const chunkMinNum = 20
|
|
@@ -19,7 +21,10 @@ const chunkMinNum = 20
|
|
|
19
21
|
export default class WorkerReplace implements ReplaceInterface {
|
|
20
22
|
#files: Temp[] = []
|
|
21
23
|
#dispatcher: DispatcherInterface
|
|
22
|
-
#tasks = new Map<string,
|
|
24
|
+
#tasks = new Map<string, {
|
|
25
|
+
resolve: (value: unknown) => void,
|
|
26
|
+
reject: (reason?: unknown) => void,
|
|
27
|
+
}>()
|
|
23
28
|
#concurrency: number = 1
|
|
24
29
|
|
|
25
30
|
constructor(dispatcher: DispatcherInterface) {
|
|
@@ -28,8 +33,8 @@ export default class WorkerReplace implements ReplaceInterface {
|
|
|
28
33
|
}
|
|
29
34
|
|
|
30
35
|
setDispatcher(dispatcher: DispatcherInterface) {
|
|
31
|
-
dispatcher.addListener(event => {
|
|
32
|
-
const data = event.data
|
|
36
|
+
dispatcher.addListener<messageData>(event => {
|
|
37
|
+
const data = event.data
|
|
33
38
|
switch (data.type) {
|
|
34
39
|
case messageTypes.methodCallReply:
|
|
35
40
|
const replyData = data.data as methodCallReply
|
|
@@ -37,33 +42,46 @@ export default class WorkerReplace implements ReplaceInterface {
|
|
|
37
42
|
return
|
|
38
43
|
}
|
|
39
44
|
const fn = this.#tasks.get(replyData.replyId)
|
|
40
|
-
if (fn) {
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
if (!fn) {
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
if (replyData.error) {
|
|
49
|
+
fn.reject(replyData.error)
|
|
50
|
+
} else {
|
|
51
|
+
fn.resolve(replyData.result)
|
|
43
52
|
}
|
|
44
|
-
|
|
53
|
+
this.#tasks.delete(replyData.replyId)
|
|
54
|
+
break
|
|
45
55
|
case messageTypes.methodCall:
|
|
46
|
-
const callData = data.data as methodCall
|
|
47
|
-
const method = callData.method
|
|
48
|
-
if (!allowCallMethodNames
|
|
56
|
+
const callData = data.data as methodCall<allMethodNames>
|
|
57
|
+
const method = callData.method
|
|
58
|
+
if (!allowCallMethodNames.has(method)) {
|
|
49
59
|
return
|
|
50
60
|
}
|
|
61
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
51
62
|
const fun = this[method] as Function | undefined
|
|
52
63
|
if (!fun) {
|
|
53
64
|
return
|
|
54
65
|
}
|
|
66
|
+
|
|
55
67
|
const callRes = fun.apply(this, callData.params)
|
|
56
68
|
if (!callData.replyId) {
|
|
57
69
|
return
|
|
58
70
|
}
|
|
59
|
-
return new Promise(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
71
|
+
return new Promise((resolve, reject) => {
|
|
72
|
+
try {
|
|
73
|
+
Promise.resolve(callRes).then(result => {
|
|
74
|
+
resolve({
|
|
75
|
+
type: messageTypes.methodCallReply,
|
|
76
|
+
data: {
|
|
77
|
+
replyId: callData.replyId,
|
|
78
|
+
result
|
|
79
|
+
},
|
|
80
|
+
})
|
|
81
|
+
}).catch(reject)
|
|
82
|
+
} catch (error) {
|
|
83
|
+
reject(error)
|
|
84
|
+
}
|
|
67
85
|
})
|
|
68
86
|
}
|
|
69
87
|
})
|
|
@@ -72,8 +90,8 @@ export default class WorkerReplace implements ReplaceInterface {
|
|
|
72
90
|
this.#concurrency = this.#dispatcher.concurrency()
|
|
73
91
|
}
|
|
74
92
|
|
|
75
|
-
#call(method:
|
|
76
|
-
const transfer:
|
|
93
|
+
#call<T>(method: allMethodNames, params: unknown[]): Promise<T> {
|
|
94
|
+
const transfer: Transferable[] = []
|
|
77
95
|
|
|
78
96
|
for (const param of params) {
|
|
79
97
|
if (param instanceof Array) {
|
|
@@ -84,39 +102,51 @@ export default class WorkerReplace implements ReplaceInterface {
|
|
|
84
102
|
}
|
|
85
103
|
}
|
|
86
104
|
}
|
|
87
|
-
|
|
88
105
|
const replyId = generateId()
|
|
89
|
-
this.#dispatcher.postMessage(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
106
|
+
this.#dispatcher.postMessage(
|
|
107
|
+
{
|
|
108
|
+
type: messageTypes.methodCall,
|
|
109
|
+
data: {
|
|
110
|
+
replyId,
|
|
111
|
+
method,
|
|
112
|
+
params,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
transfer.length ? { transfer } : undefined,
|
|
116
|
+
)
|
|
97
117
|
return new Promise((resolve, reject) => {
|
|
98
|
-
this.#tasks.set(replyId,
|
|
118
|
+
this.#tasks.set(replyId, {
|
|
119
|
+
resolve: resolve as (value: unknown) => void,
|
|
120
|
+
reject
|
|
121
|
+
})
|
|
99
122
|
})
|
|
100
123
|
}
|
|
101
124
|
|
|
102
125
|
//分片
|
|
103
|
-
#chunk<T
|
|
104
|
-
|
|
126
|
+
#chunk<T, Y = undefined>(
|
|
127
|
+
data: T[],
|
|
128
|
+
chunkPackage?: ((chunkData: T[]) => Y),
|
|
129
|
+
): T[][] | Y[] {
|
|
130
|
+
let chunks: T[][];
|
|
105
131
|
if (this.#concurrency > 1 && data.length > chunkMinNum) {
|
|
106
|
-
const chunkSize = Math.ceil(
|
|
132
|
+
const chunkSize = Math.ceil(
|
|
133
|
+
data.length / Math.round(data.length / chunkMinNum),
|
|
134
|
+
)
|
|
107
135
|
chunks = splitArrayIntoChunks<T>(data, chunkSize)
|
|
108
136
|
} else {
|
|
109
137
|
chunks = [data]
|
|
110
138
|
}
|
|
111
139
|
if (chunkPackage) {
|
|
112
140
|
for (const i in chunks) {
|
|
113
|
-
chunks[i] = chunkPackage(chunks[i])
|
|
141
|
+
(chunks as Y[])[i] = chunkPackage(chunks[i])
|
|
114
142
|
}
|
|
115
143
|
}
|
|
116
144
|
return chunks
|
|
117
145
|
}
|
|
118
146
|
|
|
119
|
-
async #getTempFileData(
|
|
147
|
+
async #getTempFileData(
|
|
148
|
+
files: Temp[] | undefined,
|
|
149
|
+
): Promise<transmitFileInfo[]> {
|
|
120
150
|
if (!files) {
|
|
121
151
|
files = this.#files
|
|
122
152
|
}
|
|
@@ -128,27 +158,29 @@ export default class WorkerReplace implements ReplaceInterface {
|
|
|
128
158
|
return res.filter(item => !!item)
|
|
129
159
|
}
|
|
130
160
|
|
|
131
|
-
|
|
132
161
|
clear(): void {
|
|
133
162
|
this.#files.length = 0
|
|
134
163
|
}
|
|
135
164
|
|
|
136
|
-
async #chunkCall(
|
|
137
|
-
|
|
165
|
+
async #chunkCall<T>(
|
|
166
|
+
method: allMethodNames,
|
|
167
|
+
paramChunks: unknown[][],
|
|
168
|
+
): Promise<Record<string, T>> {
|
|
169
|
+
const tasks: Promise<Record<string, T>>[] = []
|
|
138
170
|
for (const chunk of paramChunks) {
|
|
139
171
|
tasks.push(this.#call(method, chunk))
|
|
140
172
|
}
|
|
141
173
|
const tasksRes = await Promise.all(tasks)
|
|
142
|
-
return
|
|
143
|
-
return { ...accumulator, ...current }
|
|
144
|
-
}, {})
|
|
174
|
+
return Object.assign({}, ...tasksRes)
|
|
145
175
|
}
|
|
146
176
|
|
|
147
177
|
addTempFile(tempFile: Temp): void {
|
|
148
178
|
this.#files.push(tempFile)
|
|
149
179
|
}
|
|
150
180
|
|
|
151
|
-
async extractVariables(
|
|
181
|
+
async extractVariables(
|
|
182
|
+
files: Temp[] | undefined,
|
|
183
|
+
): Promise<Record<string, string[]>> {
|
|
152
184
|
const fileData = await this.#getTempFileData(files)
|
|
153
185
|
const chunks = this.#chunk(fileData, chunkData => {
|
|
154
186
|
return [chunkData]
|
|
@@ -156,7 +188,9 @@ export default class WorkerReplace implements ReplaceInterface {
|
|
|
156
188
|
return this.#chunkCall('extractVariables', chunks)
|
|
157
189
|
}
|
|
158
190
|
|
|
159
|
-
async extractMedias(
|
|
191
|
+
async extractMedias(
|
|
192
|
+
files: Temp[] | undefined,
|
|
193
|
+
): Promise<Record<string, media[]>> {
|
|
160
194
|
const fileData = await this.#getTempFileData(files)
|
|
161
195
|
const chunks = this.#chunk(fileData, chunkData => {
|
|
162
196
|
return [chunkData]
|
|
@@ -164,11 +198,14 @@ export default class WorkerReplace implements ReplaceInterface {
|
|
|
164
198
|
return this.#chunkCall('extractMedias', chunks)
|
|
165
199
|
}
|
|
166
200
|
|
|
167
|
-
async sign(
|
|
201
|
+
async sign(_: unknown): Promise<string> {
|
|
168
202
|
return ''
|
|
169
203
|
}
|
|
170
204
|
|
|
171
|
-
async execute(
|
|
205
|
+
async execute(
|
|
206
|
+
params: paramsData,
|
|
207
|
+
files: Temp[] | undefined,
|
|
208
|
+
): Promise<Record<string, Uint8Array>> {
|
|
172
209
|
const fileData = await this.#getTempFileData(files)
|
|
173
210
|
const chunks = this.#chunk(fileData, chunkData => {
|
|
174
211
|
return [params, chunkData]
|
|
@@ -176,28 +213,116 @@ export default class WorkerReplace implements ReplaceInterface {
|
|
|
176
213
|
return this.#chunkCall('execute', chunks)
|
|
177
214
|
}
|
|
178
215
|
|
|
179
|
-
async
|
|
216
|
+
async executeToZip(
|
|
217
|
+
params: paramsData,
|
|
218
|
+
files: Temp[] | undefined,
|
|
219
|
+
): Promise<Uint8Array> {
|
|
220
|
+
const fileData = await this.#getTempFileData(files)
|
|
221
|
+
return new Promise((resolve, reject) => {
|
|
222
|
+
const tasks: Promise<void>[] = []
|
|
223
|
+
const u8s: Uint8Array[] = [];
|
|
224
|
+
const _zip = new Zip((err, dat, final) => {
|
|
225
|
+
if (dat.length) {
|
|
226
|
+
u8s.push(dat)
|
|
227
|
+
}
|
|
228
|
+
if (final) {
|
|
229
|
+
const blob = new Blob(u8s as BlobPart[])
|
|
230
|
+
blob.arrayBuffer().then(res => {
|
|
231
|
+
resolve(new Uint8Array(res))
|
|
232
|
+
})
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
this.#chunk(fileData, chunkData => {
|
|
236
|
+
tasks.push(new Promise((resolve, reject) => {
|
|
237
|
+
//直接使用execute方法,无需解压再合并数据,性能更好
|
|
238
|
+
this.#call<Record<string, Uint8Array>>('execute', [params, chunkData]).then(res => {
|
|
239
|
+
for (const name of Object.keys(res)) {
|
|
240
|
+
const helloTxt = new ZipDeflate(name, {
|
|
241
|
+
level: 9,
|
|
242
|
+
});
|
|
243
|
+
_zip.add(helloTxt)
|
|
244
|
+
helloTxt.push(res[name] as Uint8Array, true);
|
|
245
|
+
}
|
|
246
|
+
resolve()
|
|
247
|
+
}).catch(reject)
|
|
248
|
+
}))
|
|
249
|
+
})
|
|
250
|
+
Promise.all(tasks).then(() => {
|
|
251
|
+
_zip.end()
|
|
252
|
+
})
|
|
253
|
+
})
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
async executeMultipleParams(
|
|
257
|
+
params: paramsData[],
|
|
258
|
+
files: Temp[] | undefined,
|
|
259
|
+
): Promise<Record<string, Uint8Array>[]> {
|
|
180
260
|
const fileData = await this.#getTempFileData(files)
|
|
181
|
-
const tasks: Promise<Record<string,
|
|
261
|
+
const tasks: Promise<Record<string, Uint8Array>[]>[] = []
|
|
182
262
|
this.#chunk(fileData, chunkData => {
|
|
183
|
-
tasks.push(
|
|
263
|
+
tasks.push(
|
|
264
|
+
this.#call('executeMultipleParams', [params, chunkData]),
|
|
265
|
+
)
|
|
184
266
|
})
|
|
185
|
-
const tasksRes =
|
|
186
|
-
const res =
|
|
267
|
+
const tasksRes = await Promise.all(tasks)
|
|
268
|
+
const res = Array.from({ length: params.length }, () => ({}))
|
|
187
269
|
for (const item of tasksRes) {
|
|
188
270
|
for (let index = 0; index < item.length; index++) {
|
|
189
|
-
res[index]
|
|
271
|
+
Object.assign(res[index], item[index])
|
|
190
272
|
}
|
|
191
273
|
}
|
|
192
274
|
return res
|
|
193
275
|
}
|
|
194
276
|
|
|
195
|
-
async
|
|
196
|
-
|
|
277
|
+
async executeMultipleParamsToZip(
|
|
278
|
+
params: paramsData[],
|
|
279
|
+
files: Temp[] | undefined,
|
|
280
|
+
): Promise<Uint8Array> {
|
|
281
|
+
const fileData = await this.#getTempFileData(files)
|
|
282
|
+
return new Promise(resolve => {
|
|
283
|
+
const tasks: Promise<void>[] = []
|
|
284
|
+
const u8s: Uint8Array[] = [];
|
|
285
|
+
const _zip = new Zip((err, dat, final) => {
|
|
286
|
+
if (dat.length) {
|
|
287
|
+
u8s.push(dat)
|
|
288
|
+
}
|
|
289
|
+
if (final) {
|
|
290
|
+
const blob = new Blob(u8s as BlobPart[])
|
|
291
|
+
blob.arrayBuffer().then(res => {
|
|
292
|
+
resolve(new Uint8Array(res))
|
|
293
|
+
})
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
this.#chunk(fileData, chunkData => {
|
|
298
|
+
tasks.push(new Promise((resolve, reject) => {
|
|
299
|
+
this.#call<Record<string, Uint8Array>[]>('executeMultipleParams', [params, chunkData]).then(res => {
|
|
300
|
+
for (let index = 0; index < res.length; index++) {
|
|
301
|
+
const item = res[index];
|
|
302
|
+
for (const name of Object.keys(item)) {
|
|
303
|
+
const helloTxt = new ZipDeflate(index + "/" + name, {
|
|
304
|
+
level: 9,
|
|
305
|
+
});
|
|
306
|
+
_zip.add(helloTxt)
|
|
307
|
+
helloTxt.push(item[name] as Uint8Array, true);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
resolve()
|
|
311
|
+
}).catch(reject)
|
|
312
|
+
}))
|
|
313
|
+
})
|
|
314
|
+
Promise.all(tasks).then(() => {
|
|
315
|
+
_zip.end()
|
|
316
|
+
})
|
|
317
|
+
})
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
fileEncrypt(file: Uint8Array): Promise<Uint8Array> {
|
|
321
|
+
return this.#call('fileEncrypt', [file])
|
|
197
322
|
}
|
|
198
323
|
|
|
199
324
|
async filesEncrypt(files: Uint8Array[]): Promise<Uint8Array[]> {
|
|
200
|
-
const chunks = this.#chunk<Uint8Array>(files)
|
|
325
|
+
const chunks = this.#chunk<Uint8Array>(files)
|
|
201
326
|
|
|
202
327
|
const tasks: Promise<Uint8Array[]>[] = []
|
|
203
328
|
for (const chunk of chunks) {
|
|
@@ -206,4 +331,4 @@ export default class WorkerReplace implements ReplaceInterface {
|
|
|
206
331
|
const tasksRes = await Promise.all(tasks)
|
|
207
332
|
return tasksRes.flat()
|
|
208
333
|
}
|
|
209
|
-
}
|
|
334
|
+
}
|
package/worker/main/sign.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import webworker from
|
|
2
|
-
import base from
|
|
1
|
+
import webworker from '../child/sign.ts?worker&inline'
|
|
2
|
+
import base from '../index'
|
|
3
3
|
|
|
4
4
|
export default class extends base {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
constructor(concurrency?: number) {
|
|
6
|
+
super(webworker, concurrency)
|
|
7
|
+
}
|
|
8
8
|
}
|
package/worker/type.ts
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
export enum messageTypes {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
replace,
|
|
3
|
+
replaceProgress,
|
|
4
|
+
sign,
|
|
5
|
+
signReply,
|
|
6
|
+
methodCall,
|
|
7
|
+
methodCallReply,
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export type messageData = {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
type: messageTypes
|
|
12
|
+
data: unknown | methodCall | methodCallReply
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export type methodCall = {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
export type methodCall<T = string> = {
|
|
16
|
+
replyId?: string
|
|
17
|
+
method: T
|
|
18
|
+
params: unknown[]
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export type methodCallReply = {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
replyId: string
|
|
23
|
+
result: unknown
|
|
24
|
+
error?: string
|
|
25
|
+
}
|
|
Binary file
|
|
Binary file
|