template-replacement 3.3.3 → 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 +1334 -1384
- package/dist/main/sign.js +1476 -1514
- package/dist/replace/general.js +283 -313
- package/dist/replace/sign.js +309 -327
- 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 +145 -143
- package/fileSystem/index.ts +5 -8
- package/fileSystem/interface.ts +4 -5
- package/fileSystem/opfs/index.ts +40 -36
- package/helper/index.ts +136 -125
- package/index.ts +6 -6
- package/office/zip.ts +106 -97
- package/package.json +14 -8
- package/replace/base.ts +203 -222
- package/replace/general.ts +44 -24
- package/replace/image.ts +88 -90
- package/replace/interface.ts +29 -24
- package/replace/paramsData.ts +107 -95
- package/replace/sign.ts +79 -52
- package/task/urlDownloadTask.ts +53 -55
- package/temp/index.ts +139 -124
- 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 -53
- 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-CJv023nf.js +0 -284
- package/dist/general.d.ts +0 -1
- package/dist/index-tFDVIkZX.js +0 -46
- package/dist/sign.d.ts +0 -1
package/download/index.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import
|
|
1
|
+
import Stream from './stream'
|
|
2
2
|
|
|
3
3
|
function download(fileName: string, blob: Blob): void {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
const href = window.URL.createObjectURL(blob)
|
|
5
|
+
const a = document.createElement('a')
|
|
6
|
+
a.href = href
|
|
7
|
+
a.target = 'target'
|
|
8
|
+
a.download = fileName
|
|
9
|
+
document.body.appendChild(a)
|
|
10
|
+
a.click()
|
|
11
|
+
document.body.removeChild(a)
|
|
12
|
+
window.URL.revokeObjectURL(href)
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export default (fileName: string, blob: Blob): void => {
|
|
16
|
-
|
|
16
|
+
download(fileName, blob)
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
//流式下载
|
|
20
|
-
export function stream(fileName: string, size?: number):
|
|
21
|
-
|
|
20
|
+
export function stream(fileName: string, size?: number): Stream {
|
|
21
|
+
return new Stream(fileName, size)
|
|
22
22
|
}
|
package/download/stream.ts
CHANGED
|
@@ -1,38 +1,39 @@
|
|
|
1
|
-
import streamSaver from
|
|
1
|
+
import streamSaver from 'streamsaver'
|
|
2
|
+
|
|
3
|
+
streamSaver.mitm = 'https://unpkg.com/streamsaver/mitm.html'
|
|
2
4
|
|
|
3
5
|
export function setMitm(mitm: string) {
|
|
4
|
-
|
|
6
|
+
streamSaver.mitm = mitm
|
|
5
7
|
}
|
|
6
8
|
|
|
7
9
|
export default class Stream {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
#tasks: Promise<unknown>[] = []
|
|
11
|
+
#writer: WritableStreamDefaultWriter<unknown>
|
|
12
|
+
#fileStream: WritableStream
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
constructor(fileName: string, size?: number) {
|
|
15
|
+
this.#fileStream = streamSaver.createWriteStream(fileName, {
|
|
16
|
+
size,
|
|
17
|
+
})
|
|
18
|
+
this.#writer = this.#fileStream.getWriter()
|
|
19
|
+
}
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
21
|
+
write(chunk: unknown): Promise<void> {
|
|
22
|
+
const res = this.#writer.write(chunk)
|
|
23
|
+
this.#tasks.push(res)
|
|
24
|
+
return res
|
|
25
|
+
}
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
const res = await this.writer.close()
|
|
31
|
-
this.writer.releaseLock()
|
|
32
|
-
return res
|
|
27
|
+
async close(): Promise<void> {
|
|
28
|
+
if (this.#tasks.length) {
|
|
29
|
+
await Promise.all(this.#tasks)
|
|
33
30
|
}
|
|
31
|
+
const res = await this.#writer.close()
|
|
32
|
+
this.#writer.releaseLock()
|
|
33
|
+
return res
|
|
34
|
+
}
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
36
|
+
abort(reason?: unknown): Promise<void> {
|
|
37
|
+
return this.#fileStream.abort(reason)
|
|
38
|
+
}
|
|
39
|
+
}
|
package/eslint.config.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { globalIgnores } from 'eslint/config'
|
|
2
|
+
import oxlint from 'eslint-plugin-oxlint'
|
|
3
|
+
import tseslint from '@typescript-eslint/eslint-plugin'
|
|
4
|
+
import tsParser from '@typescript-eslint/parser'
|
|
5
|
+
|
|
6
|
+
export default [
|
|
7
|
+
{
|
|
8
|
+
name: 'app/files-to-lint',
|
|
9
|
+
files: ['**/*.{ts,mts,tsx}'],
|
|
10
|
+
languageOptions: {
|
|
11
|
+
parser: tsParser,
|
|
12
|
+
parserOptions: {
|
|
13
|
+
ecmaVersion: 'latest',
|
|
14
|
+
sourceType: 'module',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
plugins: {
|
|
18
|
+
'@typescript-eslint': tseslint,
|
|
19
|
+
},
|
|
20
|
+
rules: {
|
|
21
|
+
...tseslint.configs.recommended.rules,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
globalIgnores(['/dist/**', '/node_modules/**']),
|
|
26
|
+
|
|
27
|
+
...oxlint.configs['flat/recommended'], // oxlint should be the last one
|
|
28
|
+
]
|
package/fileSystem/db/index.ts
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
import indexedDBCache from './indexedDBCache'
|
|
2
|
-
import FileSystem, {fileDataType} from '../interface'
|
|
2
|
+
import FileSystem, { fileDataType } from '../interface'
|
|
3
3
|
|
|
4
4
|
const db = new indexedDBCache()
|
|
5
5
|
|
|
6
6
|
export default class DbFile implements FileSystem {
|
|
7
|
-
|
|
7
|
+
#name: string
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
constructor(name: string = '') {
|
|
10
|
+
this.#name = name
|
|
11
|
+
}
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
13
|
+
async write(data: fileDataType): Promise<boolean> {
|
|
14
|
+
try {
|
|
15
|
+
await db.putData<File>({
|
|
16
|
+
key: this.#name,
|
|
17
|
+
data: new File([data], this.#name),
|
|
18
|
+
})
|
|
19
|
+
return true
|
|
20
|
+
} catch (error) {
|
|
21
|
+
console.error(error)
|
|
22
|
+
return false
|
|
24
23
|
}
|
|
24
|
+
}
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
return new File([], this.#name)
|
|
26
|
+
async read(): Promise<File> {
|
|
27
|
+
const data = await db.getDataByKey<File>(this.#name)
|
|
28
|
+
if (data && data.data) {
|
|
29
|
+
return data.data
|
|
32
30
|
}
|
|
31
|
+
return new File([], this.#name)
|
|
32
|
+
}
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
remove(): Promise<void> {
|
|
35
|
+
return db.deleteDataByKey(this.#name)
|
|
36
|
+
}
|
|
37
37
|
}
|
|
@@ -1,161 +1,163 @@
|
|
|
1
|
-
import _init from '../../worker/child/base';
|
|
2
|
-
|
|
3
1
|
type templateData<T> = {
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
key: string // 主键
|
|
3
|
+
data: T // 文件数据
|
|
6
4
|
}
|
|
7
5
|
|
|
8
6
|
export default class indexedDBCache {
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
private _initFinishCallBackFuns?: ((value: void) => void)[] = [] //初始化完成回调
|
|
8
|
+
#isInitFinish: boolean = false //是否初始化完成
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
_tableMap: unknown = {} //表配置
|
|
10
|
+
private _db?: IDBDatabase //数据库
|
|
11
|
+
#dbName: string = 'template_replacement_db' //数据库名
|
|
12
|
+
#dbversion: number = 1 //数据库版本
|
|
13
|
+
#cacheTableName: string = 'template_files' //表名
|
|
17
14
|
|
|
18
|
-
|
|
15
|
+
private _init: Promise<unknown> | undefined
|
|
19
16
|
|
|
17
|
+
// 构造函数
|
|
18
|
+
constructor() {
|
|
19
|
+
this.#initDB()
|
|
20
|
+
}
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
#initDB(): Promise<unknown> {
|
|
23
|
+
if (this._init) {
|
|
24
|
+
return this._init
|
|
24
25
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
this
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
this._isInitFinish = true
|
|
36
|
-
if (this._initFinishCallBackFuns) {
|
|
37
|
-
try {
|
|
38
|
-
for (const fun of this._initFinishCallBackFuns) {
|
|
39
|
-
fun()
|
|
40
|
-
}
|
|
41
|
-
} catch (error) {
|
|
42
|
-
}
|
|
43
|
-
this._initFinishCallBackFuns = undefined
|
|
44
|
-
}
|
|
45
|
-
resolve(event)
|
|
26
|
+
this._init = new Promise((resolve, reject) => {
|
|
27
|
+
const request = indexedDB.open(this.#dbName, this.#dbversion) // 打开数据库
|
|
28
|
+
// 数据库初始化成功
|
|
29
|
+
request.onsuccess = (event) => {
|
|
30
|
+
this._db = request.result
|
|
31
|
+
this.#isInitFinish = true
|
|
32
|
+
if (this._initFinishCallBackFuns) {
|
|
33
|
+
try {
|
|
34
|
+
for (const fun of this._initFinishCallBackFuns) {
|
|
35
|
+
fun()
|
|
46
36
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
console.error(event)
|
|
50
|
-
reject(event)
|
|
51
|
-
}
|
|
52
|
-
// 数据库初次创建或更新时会触发
|
|
53
|
-
request.onupgradeneeded = (event) => {
|
|
54
|
-
let db = request.result
|
|
55
|
-
if (!db.objectStoreNames.contains(this._cacheTableName)) {
|
|
56
|
-
db.createObjectStore(this._cacheTableName, {
|
|
57
|
-
keyPath: 'key', // 设置主键
|
|
58
|
-
})
|
|
59
|
-
}
|
|
60
|
-
resolve(event)
|
|
61
|
-
}
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
return this._init
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
async awaitInit(): Promise<void> {
|
|
68
|
-
if(this._isInitFinish || !this._initFinishCallBackFuns) {
|
|
69
|
-
return
|
|
37
|
+
} catch (error) { }
|
|
38
|
+
this._initFinishCallBackFuns = undefined
|
|
70
39
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
40
|
+
resolve(event)
|
|
41
|
+
}
|
|
42
|
+
// 数据库初始化失败
|
|
43
|
+
request.onerror = (event) => {
|
|
44
|
+
console.error(event)
|
|
45
|
+
reject(event)
|
|
46
|
+
}
|
|
47
|
+
// 数据库初次创建或更新时会触发
|
|
48
|
+
request.onupgradeneeded = (event) => {
|
|
49
|
+
let db = request.result
|
|
50
|
+
if (!db.objectStoreNames.contains(this.#cacheTableName)) {
|
|
51
|
+
db.createObjectStore(this.#cacheTableName, {
|
|
52
|
+
keyPath: 'key', // 设置主键
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
resolve(event)
|
|
56
|
+
}
|
|
57
|
+
})
|
|
75
58
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
59
|
+
return this._init
|
|
60
|
+
}
|
|
79
61
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const transaction = db.transaction(this._cacheTableName, mode)
|
|
84
|
-
return transaction.objectStore(this._cacheTableName)
|
|
62
|
+
async awaitInit(): Promise<void> {
|
|
63
|
+
if (this.#isInitFinish || !this._initFinishCallBackFuns) {
|
|
64
|
+
return
|
|
85
65
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
66
|
+
await new Promise((resolve, reject) => {
|
|
67
|
+
this._initFinishCallBackFuns?.push(resolve)
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
closeDB(): void {
|
|
72
|
+
this._db?.close()
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async store(mode?: IDBTransactionMode): Promise<IDBObjectStore> {
|
|
76
|
+
await this.awaitInit()
|
|
77
|
+
const db = this._db as IDBDatabase
|
|
78
|
+
const transaction = db.transaction(this.#cacheTableName, mode)
|
|
79
|
+
return transaction.objectStore(this.#cacheTableName)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @description : 更新数据
|
|
84
|
+
* @param {templateData} params 添加到数据库中的数据 { key: 文件key, data: 文件blob }
|
|
85
|
+
* @return {*}
|
|
86
|
+
*/
|
|
87
|
+
putData<T>(params: templateData<T>): Promise<unknown> {
|
|
88
|
+
return new Promise((resolve, reject) => {
|
|
89
|
+
this.store('readwrite')
|
|
90
|
+
.then((store) => {
|
|
91
|
+
const response = store.put(params)
|
|
92
|
+
// 操作成功
|
|
93
|
+
response.onsuccess = (event) => {
|
|
94
|
+
resolve(event)
|
|
95
|
+
}
|
|
96
|
+
// 操作失败
|
|
97
|
+
response.onerror = (event) => {
|
|
98
|
+
reject(event)
|
|
99
|
+
}
|
|
105
100
|
})
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
101
|
+
.catch(reject)
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// 通过主键读取数据
|
|
106
|
+
getDataByKey<T>(key: string): Promise<templateData<T>> {
|
|
107
|
+
return new Promise((resolve, reject) => {
|
|
108
|
+
this.store()
|
|
109
|
+
.then((store) => {
|
|
110
|
+
// 通过主键读取数据
|
|
111
|
+
const request = store.get(key)
|
|
112
|
+
// 操作成功
|
|
113
|
+
request.onsuccess = () => {
|
|
114
|
+
resolve(request.result)
|
|
115
|
+
}
|
|
116
|
+
// 操作失败
|
|
117
|
+
request.onerror = (event) => {
|
|
118
|
+
reject(event)
|
|
119
|
+
}
|
|
123
120
|
})
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
121
|
+
.catch(reject)
|
|
122
|
+
})
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 通过主键移除数据
|
|
126
|
+
deleteDataByKey(key: string): Promise<void> {
|
|
127
|
+
return new Promise((resolve, reject) => {
|
|
128
|
+
this.store()
|
|
129
|
+
.then((store) => {
|
|
130
|
+
// 通过主键读取数据
|
|
131
|
+
const request = store.delete(key)
|
|
132
|
+
// 操作成功
|
|
133
|
+
request.onsuccess = () => {
|
|
134
|
+
resolve(request.result)
|
|
135
|
+
}
|
|
136
|
+
// 操作失败
|
|
137
|
+
request.onerror = (event) => {
|
|
138
|
+
reject(event)
|
|
139
|
+
}
|
|
141
140
|
})
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
141
|
+
.catch(reject)
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// 清空数据库数据
|
|
146
|
+
clearDB(): Promise<unknown> {
|
|
147
|
+
return new Promise((resolve, reject) => {
|
|
148
|
+
this.store('readwrite')
|
|
149
|
+
.then((store) => {
|
|
150
|
+
const response = store.clear()
|
|
151
|
+
// 操作成功
|
|
152
|
+
response.onsuccess = (event) => {
|
|
153
|
+
resolve(event)
|
|
154
|
+
}
|
|
155
|
+
// 操作失败
|
|
156
|
+
response.onerror = (event) => {
|
|
157
|
+
reject(event)
|
|
158
|
+
}
|
|
158
159
|
})
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
160
|
+
.catch(reject)
|
|
161
|
+
})
|
|
162
|
+
}
|
|
163
|
+
}
|
package/fileSystem/index.ts
CHANGED
|
@@ -2,12 +2,9 @@ import FileSystem from './interface'
|
|
|
2
2
|
import OpfsFile from './opfs'
|
|
3
3
|
import DbFile from './db'
|
|
4
4
|
|
|
5
|
-
export default (name: string): FileSystem =>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
export default (name: string): FileSystem => {
|
|
6
|
+
if ('storage' in navigator && typeof navigator.storage.getDirectory === 'function') {
|
|
7
|
+
return new OpfsFile(name)
|
|
8
|
+
}
|
|
9
|
+
return new DbFile(name)
|
|
10
10
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
package/fileSystem/interface.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
|
|
2
1
|
export type fileDataType = BufferSource | Blob | string
|
|
3
2
|
|
|
4
3
|
export default interface FileSystem {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
4
|
+
write(data: fileDataType): Promise<boolean>
|
|
5
|
+
read(): Promise<File>
|
|
6
|
+
remove(): Promise<void>
|
|
7
|
+
}
|
package/fileSystem/opfs/index.ts
CHANGED
|
@@ -1,48 +1,52 @@
|
|
|
1
|
-
import FileSystem, {fileDataType} from '../interface'
|
|
1
|
+
import FileSystem, { fileDataType } from '../interface'
|
|
2
2
|
|
|
3
3
|
let opfsRoot: FileSystemDirectoryHandle | undefined = undefined
|
|
4
4
|
|
|
5
5
|
async function getOpfsRoot(): Promise<FileSystemDirectoryHandle> {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
if (!opfsRoot) {
|
|
7
|
+
opfsRoot = await (
|
|
8
|
+
await navigator.storage.getDirectory()
|
|
9
|
+
).getDirectoryHandle('template_replacement', {
|
|
10
|
+
create: true,
|
|
11
|
+
})
|
|
12
|
+
}
|
|
13
|
+
return opfsRoot
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export default class OpfsFile implements FileSystem {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
#name: string = ''
|
|
18
|
+
private _handle: FileSystemFileHandle | undefined
|
|
19
|
+
|
|
20
|
+
constructor(name: string) {
|
|
21
|
+
this.#name = name
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async getHandle(): Promise<FileSystemFileHandle> {
|
|
25
|
+
if (!this._handle) {
|
|
26
|
+
this._handle = await (
|
|
27
|
+
await getOpfsRoot()
|
|
28
|
+
).getFileHandle(this.#name, { create: true })
|
|
20
29
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
return this._handle
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async write(data: fileDataType): Promise<boolean> {
|
|
34
|
+
try {
|
|
35
|
+
const writable = await (await this.getHandle()).createWritable()
|
|
36
|
+
await writable.write(data)
|
|
37
|
+
await writable.close()
|
|
38
|
+
return true
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.error(error)
|
|
41
|
+
return false
|
|
27
42
|
}
|
|
43
|
+
}
|
|
28
44
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
await writable.write(data)
|
|
33
|
-
await writable.close()
|
|
34
|
-
return true
|
|
35
|
-
} catch (error) {
|
|
36
|
-
console.error(error)
|
|
37
|
-
return false
|
|
38
|
-
}
|
|
39
|
-
}
|
|
45
|
+
async read(): Promise<File> {
|
|
46
|
+
return (await this.getHandle()).getFile()
|
|
47
|
+
}
|
|
40
48
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
async remove(): Promise<void> {
|
|
46
|
-
return (await getOpfsRoot()).removeEntry(this.#name)
|
|
47
|
-
}
|
|
49
|
+
async remove(): Promise<void> {
|
|
50
|
+
return (await getOpfsRoot()).removeEntry(this.#name)
|
|
51
|
+
}
|
|
48
52
|
}
|