@dsh-plus/image-studio 0.1.18 → 0.1.19
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/lib/index.js +6 -10
- package/package.json +2 -2
- package/src/gallery/store.ts +7 -9
- package/src/uploads/store.ts +6 -8
package/lib/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Service } from "@deepseek-ai/cordis";
|
|
2
2
|
import { credentialRef } from "@deepseek-ai/dsh-credentials";
|
|
3
|
-
import { pluginDataPath, unwrapVolatile } from "@dsh-plus/shared";
|
|
3
|
+
import { atomicWriteFile, commitTmpFile, pluginDataPath, unwrapVolatile } from "@dsh-plus/shared";
|
|
4
4
|
import { request } from "node:http";
|
|
5
5
|
import { request as request$1 } from "node:https";
|
|
6
6
|
import { HttpsProxyAgent } from "https-proxy-agent";
|
|
7
7
|
import { randomUUID } from "node:crypto";
|
|
8
|
-
import { appendFile, mkdir, readFile, readdir,
|
|
8
|
+
import { appendFile, mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import z from "@deepseek-ai/schemastery";
|
|
11
11
|
//#region src/errors.ts
|
|
@@ -1068,7 +1068,7 @@ async function saveGalleryItem(input) {
|
|
|
1068
1068
|
const target = imagePathOf(imageId, extOfMime(image.mime));
|
|
1069
1069
|
const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
1070
1070
|
await writeFile(tmp, image.data);
|
|
1071
|
-
await
|
|
1071
|
+
await commitTmpFile(tmp, target);
|
|
1072
1072
|
imageIds.push(imageId);
|
|
1073
1073
|
}
|
|
1074
1074
|
const item = {
|
|
@@ -1091,9 +1091,7 @@ async function deleteGalleryItem(itemId) {
|
|
|
1091
1091
|
for (const name of files) if (name.startsWith(`${imageId}.`)) await rm(join(imagesDir(), name), { force: true });
|
|
1092
1092
|
}
|
|
1093
1093
|
const kept = items.filter((item) => item.id !== itemId);
|
|
1094
|
-
|
|
1095
|
-
await writeFile(tmp, kept.map((item) => JSON.stringify(item)).join("\n") + (kept.length > 0 ? "\n" : ""), "utf8");
|
|
1096
|
-
await rename(tmp, indexFile$1());
|
|
1094
|
+
await atomicWriteFile(indexFile$1(), kept.map((item) => JSON.stringify(item)).join("\n") + (kept.length > 0 ? "\n" : ""));
|
|
1097
1095
|
return true;
|
|
1098
1096
|
}
|
|
1099
1097
|
//#endregion
|
|
@@ -1296,7 +1294,7 @@ async function saveUpload(input) {
|
|
|
1296
1294
|
const target = blobPathOf(id, ext);
|
|
1297
1295
|
const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
1298
1296
|
await writeFile(tmp, input.data);
|
|
1299
|
-
await
|
|
1297
|
+
await commitTmpFile(tmp, target);
|
|
1300
1298
|
const entry = {
|
|
1301
1299
|
id,
|
|
1302
1300
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -1325,9 +1323,7 @@ async function removeUpload(entry) {
|
|
|
1325
1323
|
}
|
|
1326
1324
|
/** 索引导出为 JSONL(重写式删除的公共收尾)。 */
|
|
1327
1325
|
async function rewriteIndex(kept) {
|
|
1328
|
-
|
|
1329
|
-
await writeFile(tmp, kept.map((item) => JSON.stringify(item)).join("\n") + (kept.length > 0 ? "\n" : ""), "utf8");
|
|
1330
|
-
await rename(tmp, indexFile());
|
|
1326
|
+
await atomicWriteFile(indexFile(), kept.map((item) => JSON.stringify(item)).join("\n") + (kept.length > 0 ? "\n" : ""));
|
|
1331
1327
|
}
|
|
1332
1328
|
/**
|
|
1333
1329
|
* 回收孤儿上传:未被 keepIds 引用且创建时间早于 ttlMs 的条目删除。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dsh-plus/image-studio",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
4
4
|
"description": "dsh-plus service+ui plugin: 图像工作室——OpenAI Images 协议文生图/图生图,全参数开关化,双预设体系,并发生图任务与可二次编辑画廊",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"https-proxy-agent": "^9.1.0",
|
|
23
|
-
"@dsh-plus/shared": "0.1.
|
|
23
|
+
"@dsh-plus/shared": "0.1.27"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"@deepseek-ai/cordis": "^4.0.4",
|
package/src/gallery/store.ts
CHANGED
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { randomUUID } from 'node:crypto'
|
|
10
|
-
import { appendFile, mkdir, readdir, readFile,
|
|
10
|
+
import { appendFile, mkdir, readdir, readFile, rm, writeFile } from 'node:fs/promises'
|
|
11
11
|
import { join } from 'node:path'
|
|
12
12
|
|
|
13
|
-
import { pluginDataPath } from '@dsh-plus/shared'
|
|
13
|
+
import { atomicWriteFile, commitTmpFile, pluginDataPath } from '@dsh-plus/shared'
|
|
14
14
|
import { isImageId } from '../images/id.ts'
|
|
15
15
|
import { extOfMime } from '../images/mime.ts'
|
|
16
16
|
import type { ImageEndpoint } from '../provider/types.ts'
|
|
@@ -121,11 +121,12 @@ export async function saveGalleryItem(input: {
|
|
|
121
121
|
for (const image of input.images) {
|
|
122
122
|
const imageId = randomUUID()
|
|
123
123
|
const ext = extOfMime(image.mime)
|
|
124
|
-
//
|
|
124
|
+
// 图片是字节(官方 writeFileAtomic 仅收字符串):tmp 落盘 + commitTmpFile
|
|
125
|
+
// rename 提交,rename 被占用时回退复制,中断不留半截图片。
|
|
125
126
|
const target = imagePathOf(imageId, ext)
|
|
126
127
|
const tmp = `${target}.tmp-${process.pid}-${Date.now()}`
|
|
127
128
|
await writeFile(tmp, image.data)
|
|
128
|
-
await
|
|
129
|
+
await commitTmpFile(tmp, target)
|
|
129
130
|
imageIds.push(imageId)
|
|
130
131
|
}
|
|
131
132
|
const item: GalleryItem = {
|
|
@@ -153,13 +154,10 @@ export async function deleteGalleryItem(itemId: string): Promise<boolean> {
|
|
|
153
154
|
}
|
|
154
155
|
}
|
|
155
156
|
const kept = items.filter((item) => item.id !== itemId)
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
tmp,
|
|
157
|
+
await atomicWriteFile(
|
|
158
|
+
indexFile(),
|
|
159
159
|
kept.map((item) => JSON.stringify(item)).join('\n') + (kept.length > 0 ? '\n' : ''),
|
|
160
|
-
'utf8',
|
|
161
160
|
)
|
|
162
|
-
await rename(tmp, indexFile())
|
|
163
161
|
return true
|
|
164
162
|
}
|
|
165
163
|
|
package/src/uploads/store.ts
CHANGED
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { randomUUID } from 'node:crypto'
|
|
11
|
-
import { appendFile, mkdir, readdir, readFile,
|
|
11
|
+
import { appendFile, mkdir, readdir, readFile, rm, writeFile } from 'node:fs/promises'
|
|
12
12
|
import { join } from 'node:path'
|
|
13
13
|
|
|
14
|
-
import { pluginDataPath } from '@dsh-plus/shared'
|
|
14
|
+
import { atomicWriteFile, commitTmpFile, pluginDataPath } from '@dsh-plus/shared'
|
|
15
15
|
import { isImageId } from '../images/id.ts'
|
|
16
16
|
import { extOfMime } from '../images/mime.ts'
|
|
17
17
|
|
|
@@ -96,9 +96,10 @@ export async function saveUpload(input: {
|
|
|
96
96
|
const id = randomUUID()
|
|
97
97
|
const ext = extOfMime(input.mime)
|
|
98
98
|
const target = blobPathOf(id, ext)
|
|
99
|
+
// 字节走 tmp + commitTmpFile(官方 writeFileAtomic 仅收字符串)。
|
|
99
100
|
const tmp = `${target}.tmp-${process.pid}-${Date.now()}`
|
|
100
101
|
await writeFile(tmp, input.data)
|
|
101
|
-
await
|
|
102
|
+
await commitTmpFile(tmp, target)
|
|
102
103
|
const entry: UploadEntry = {
|
|
103
104
|
id,
|
|
104
105
|
createdAt: new Date().toISOString(),
|
|
@@ -128,13 +129,10 @@ async function removeUpload(entry: UploadEntry): Promise<void> {
|
|
|
128
129
|
|
|
129
130
|
/** 索引导出为 JSONL(重写式删除的公共收尾)。 */
|
|
130
131
|
async function rewriteIndex(kept: UploadEntry[]): Promise<void> {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
tmp,
|
|
132
|
+
await atomicWriteFile(
|
|
133
|
+
indexFile(),
|
|
134
134
|
kept.map((item) => JSON.stringify(item)).join('\n') + (kept.length > 0 ? '\n' : ''),
|
|
135
|
-
'utf8',
|
|
136
135
|
)
|
|
137
|
-
await rename(tmp, indexFile())
|
|
138
136
|
}
|
|
139
137
|
|
|
140
138
|
/**
|