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.
Files changed (47) hide show
  1. package/.workflow/publish_to_npmjs.yml +26 -0
  2. package/core/base.ts +54 -0
  3. package/core/general.ts +13 -0
  4. package/core/sign.ts +13 -0
  5. package/db/index.ts +5 -0
  6. package/db/indexedDBCache.ts +129 -0
  7. package/dispatcher/general.ts +6 -0
  8. package/dispatcher/sign.ts +6 -0
  9. package/dispatcher/workerGeneral.ts +7 -0
  10. package/dispatcher/workerSign.ts +7 -0
  11. package/dist/assets/template_replacement_core_wasm_bg.wasm +0 -0
  12. package/dist/assets/template_replacement_sign_core_wasm_bg.wasm +0 -0
  13. package/dist/base-CC-6cmrq.js +189 -0
  14. package/dist/general.d.ts +1 -0
  15. package/dist/index-BkwrGCka.js +61 -0
  16. package/dist/main/general.js +4543 -0
  17. package/dist/main/sign.js +4566 -0
  18. package/dist/replace/general.js +424 -0
  19. package/dist/replace/sign.js +428 -0
  20. package/dist/sign.d.ts +1 -0
  21. package/download/index.ts +22 -0
  22. package/download/stream.ts +38 -0
  23. package/helper/index.ts +162 -0
  24. package/index.ts +21 -0
  25. package/office/zip.ts +116 -0
  26. package/package.json +33 -0
  27. package/replace/base.ts +124 -0
  28. package/replace/general.ts +14 -0
  29. package/replace/image.ts +116 -0
  30. package/replace/interface.ts +29 -0
  31. package/replace/paramsData.ts +117 -0
  32. package/replace/sign.ts +31 -0
  33. package/task/urlDownloadTask.ts +67 -0
  34. package/temp/index.ts +157 -0
  35. package/temp/interface.ts +18 -0
  36. package/tsconfig.json +108 -0
  37. package/vite.config.ts +36 -0
  38. package/worker/child/agency.ts +78 -0
  39. package/worker/child/base.ts +89 -0
  40. package/worker/child/general.ts +5 -0
  41. package/worker/child/sign.ts +9 -0
  42. package/worker/index.ts +65 -0
  43. package/worker/interface.ts +11 -0
  44. package/worker/main/general.ts +8 -0
  45. package/worker/main/index.ts +176 -0
  46. package/worker/main/sign.ts +8 -0
  47. 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
+ })
@@ -0,0 +1,5 @@
1
+ import Replace from '../../replace/general';
2
+ import init from './base';
3
+
4
+ init(new Replace())
5
+
@@ -0,0 +1,9 @@
1
+ import Replace from '../../replace/sign';
2
+ import init, { call } from './base';
3
+
4
+ const replace = new Replace()
5
+ init(replace)
6
+
7
+ replace.sign = async (data: any): Promise<string> => {
8
+ return await call<string>('sign', data)
9
+ }
@@ -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,8 @@
1
+ import webworker from "../child/general.ts?worker&inline"
2
+ import base from ".."
3
+
4
+ export default class extends base {
5
+ constructor(concurrency?: number) {
6
+ super(webworker, concurrency)
7
+ }
8
+ }
@@ -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
+ }
@@ -0,0 +1,8 @@
1
+ import webworker from "../child/sign.ts?worker&inline"
2
+ import base from ".."
3
+
4
+ export default class extends base {
5
+ constructor(concurrency?: number) {
6
+ super(webworker, concurrency)
7
+ }
8
+ }
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
+ }