@yefengr/pi-reach 0.0.6 → 0.0.7

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 (45) hide show
  1. package/dist/files/content-type.d.ts +16 -0
  2. package/dist/files/content-type.js +98 -0
  3. package/dist/files/content-type.js.map +1 -0
  4. package/dist/files/image-structure.d.ts +21 -0
  5. package/dist/files/image-structure.js +269 -0
  6. package/dist/files/image-structure.js.map +1 -0
  7. package/dist/files/publications.d.ts +26 -0
  8. package/dist/files/publications.js +136 -0
  9. package/dist/files/publications.js.map +1 -0
  10. package/dist/files/publish-tool.d.ts +23 -0
  11. package/dist/files/publish-tool.js +70 -0
  12. package/dist/files/publish-tool.js.map +1 -0
  13. package/dist/files/reader.d.ts +66 -0
  14. package/dist/files/reader.js +416 -0
  15. package/dist/files/reader.js.map +1 -0
  16. package/dist/files/safe-open.d.ts +22 -0
  17. package/dist/files/safe-open.js +119 -0
  18. package/dist/files/safe-open.js.map +1 -0
  19. package/dist/index.js +12 -17
  20. package/dist/index.js.map +1 -1
  21. package/dist/runtime/file_binding.d.ts +25 -0
  22. package/dist/runtime/file_binding.js +49 -0
  23. package/dist/runtime/file_binding.js.map +1 -0
  24. package/dist/runtime/session_frame_router.d.ts +11 -0
  25. package/dist/runtime/session_frame_router.js +25 -0
  26. package/dist/runtime/session_frame_router.js.map +1 -0
  27. package/dist/timeline/runtime.d.ts +1 -1
  28. package/dist/timeline/runtime.js +26 -54
  29. package/dist/timeline/runtime.js.map +1 -1
  30. package/dist/timeline/system_event.d.ts +7 -0
  31. package/dist/timeline/system_event.js +58 -0
  32. package/dist/timeline/system_event.js.map +1 -0
  33. package/dist/timeline/tool_lifecycle.js +8 -2
  34. package/dist/timeline/tool_lifecycle.js.map +1 -1
  35. package/dist/timeline/v2_service.js +3 -0
  36. package/dist/timeline/v2_service.js.map +1 -1
  37. package/dist/vendor/protocol/session/files.d.ts +83 -0
  38. package/dist/vendor/protocol/session/files.js +162 -0
  39. package/dist/vendor/protocol/session/frames.d.ts +293 -18
  40. package/dist/vendor/protocol/session/frames.js +52 -2
  41. package/dist/vendor/protocol/session/index.d.ts +1 -0
  42. package/dist/vendor/protocol/session/index.js +1 -0
  43. package/dist/vendor/protocol/session/schema.d.ts +2 -2
  44. package/dist/vendor/protocol/session/schema.js +2 -0
  45. package/package.json +2 -2
@@ -0,0 +1,70 @@
1
+ import { resolve } from "node:path";
2
+ import { statSync } from "node:fs";
3
+ import { PUBLISHED_FILE_TYPE } from "../vendor/protocol/session/index.js";
4
+ import { Type } from "typebox";
5
+ import { publicationDataSchema, PUBLISHED_FILE_TOOL_NAME } from "./publications.js";
6
+ const parameters = Type.Object({ path: Type.String({ minLength: 1 }) }, { additionalProperties: false });
7
+ const FAILURE_TEXT = "文件发布失败";
8
+ function storedSession(manager, file) {
9
+ try {
10
+ return manager.isPersisted() && !!file && statSync(file).isFile();
11
+ }
12
+ catch {
13
+ return false;
14
+ }
15
+ }
16
+ export function createPublishFileTool(options) {
17
+ // SDK sequential 是调度约束;此门禁也阻止意外重入或嵌套直接调用。
18
+ let executing = false;
19
+ return {
20
+ name: PUBLISHED_FILE_TOOL_NAME,
21
+ label: "发布文件",
22
+ description: "仅发布面向用户交付的成果,或用户明确要求的文件;不要自动发布所有读取、修改或临时文件。已授权 PWA 可能自动获取受支持的小图片。path 相对当前工作目录或为绝对路径,允许项目外的普通文件;只保存引用,不复制原件。",
23
+ parameters,
24
+ executionMode: "sequential",
25
+ async execute(toolCallId, args, signal, _onUpdate, ctx) {
26
+ if (executing)
27
+ throw new Error(FAILURE_TEXT);
28
+ executing = true;
29
+ try {
30
+ const manager = options.getManager();
31
+ const generation = options.getGeneration();
32
+ const groupId = options.getGroupId();
33
+ if (!manager)
34
+ throw new Error(FAILURE_TEXT);
35
+ const sessionId = manager.getSessionId();
36
+ const sessionFile = manager.getSessionFile();
37
+ const valid = () => options.isCurrent() && !signal?.aborted && !ctx.signal?.aborted
38
+ && options.getGeneration() === generation && options.getManager() === manager
39
+ && ctx.sessionManager === manager && ctx.sessionManager.getSessionId() === sessionId
40
+ && manager.getSessionId() === sessionId && manager.getSessionFile() === sessionFile
41
+ && storedSession(manager, sessionFile);
42
+ if (!valid() || typeof args.path !== "string" || !args.path || args.path.includes("\0"))
43
+ throw new Error(FAILURE_TEXT);
44
+ const inspected = await options.inspect(resolve(ctx.cwd, args.path));
45
+ const data = publicationDataSchema.parse({
46
+ source_path: inspected.sourcePath,
47
+ file_name: inspected.fileName,
48
+ mime_type: inspected.mimeType,
49
+ byte_length: inspected.byteLength,
50
+ tool_call_id: toolCallId,
51
+ ...(groupId === null ? {} : { group_id: groupId }),
52
+ });
53
+ if (!valid())
54
+ throw new Error(FAILURE_TEXT);
55
+ const text = `已发布文件引用:${data.file_name} · ${data.mime_type} · ${data.byte_length} B`;
56
+ const publicationId = manager.appendCustomEntry(PUBLISHED_FILE_TYPE, data);
57
+ // append 后没有可失败的 await;正式资格由随后落盘的成功原生 toolResult 建立。
58
+ return { content: [{ type: "text", text }], details: { publication_id: publicationId } };
59
+ }
60
+ catch {
61
+ // SDK 会将 throw 转为 isError;不把内部路径或 I/O 异常暴露给消息与日志。
62
+ throw new Error(FAILURE_TEXT);
63
+ }
64
+ finally {
65
+ executing = false;
66
+ }
67
+ },
68
+ };
69
+ }
70
+ //# sourceMappingURL=publish-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish-tool.js","sourceRoot":"","sources":["../../src/files/publish-tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ import { type ClientFrame, type ServerFrame } from "../vendor/protocol/session/index.js";
2
+ export type FileScope = {
3
+ ownerId: string;
4
+ channelId: string;
5
+ runtimeId: string;
6
+ sessionId: string;
7
+ generation: number;
8
+ };
9
+ type Request = Extract<ClientFrame, {
10
+ type: "file_open" | "file_read" | "file_close";
11
+ }>;
12
+ type Response = Extract<ServerFrame, {
13
+ type: "file_opened" | "file_chunk" | "file_closed" | "file_error";
14
+ }>;
15
+ type Options = {
16
+ resolve: (scope: FileScope, publicationId: string) => {
17
+ sourcePath: string;
18
+ } | null | Promise<{
19
+ sourcePath: string;
20
+ } | null>;
21
+ isCurrent: (scope: FileScope) => boolean;
22
+ idleMs?: number;
23
+ maxResources?: number;
24
+ };
25
+ /** 所有异步任务共享额度;失效不等于内核 I/O 已停止或句柄已关闭。 */
26
+ export declare class FileReaderRuntime {
27
+ private readonly options;
28
+ private readonly resources;
29
+ private readonly opens;
30
+ private readonly idleMs;
31
+ private readonly maxResources;
32
+ private timer?;
33
+ private timerDeadline?;
34
+ private disposed;
35
+ constructor(options: Options);
36
+ get resourceCount(): number;
37
+ private reserve;
38
+ private schedule;
39
+ private invalidate;
40
+ private assertCurrent;
41
+ private eligible;
42
+ private checked;
43
+ private release;
44
+ private closeHandle;
45
+ private cleanup;
46
+ private finish;
47
+ private reply;
48
+ private failure;
49
+ handle(frame: Request, suppliedScope: FileScope): Promise<Response>;
50
+ private open;
51
+ private openResponse;
52
+ private openTask;
53
+ private verify;
54
+ private readTask;
55
+ private read;
56
+ inspectForPublication(path: string): Promise<{
57
+ sourcePath: string;
58
+ fileName: string;
59
+ mimeType: string;
60
+ byteLength: number;
61
+ }>;
62
+ private inspectTask;
63
+ closeWhere(predicate: (scope: FileScope) => boolean): Promise<void>;
64
+ dispose(): Promise<void>;
65
+ }
66
+ export {};
@@ -0,0 +1,416 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { lstat, realpath } from "node:fs/promises";
3
+ import { basename, dirname, parse } from "node:path";
4
+ import { FILE_CHUNK_BYTES, FILE_MAX_BYTES } from "../vendor/protocol/session/index.js";
5
+ import { inspectFile } from "./content-type.js";
6
+ import { FileAccessError, openSourceFile } from "./safe-open.js";
7
+ const DEFAULT_IDLE_MS = 30_000;
8
+ const DEFAULT_MAX_RESOURCES = 8;
9
+ // reload 后仍持有的资源继续占额;共享账本只存租约,不复用实例回调或 scope。
10
+ const RESOURCE_LEDGER = Symbol.for("pi-reach:file-reader:resource-leases");
11
+ const processState = globalThis;
12
+ const processLeases = processState[RESOURCE_LEDGER] ??= new Set();
13
+ function sameFile(a, b) {
14
+ return a.dev === b.dev && a.ino === b.ino && a.mode === b.mode && a.size === b.size
15
+ && a.mtimeNs === b.mtimeNs && a.ctimeNs === b.ctimeNs;
16
+ }
17
+ function errorCode(error) {
18
+ return error instanceof FileAccessError ? error.code : "io_error";
19
+ }
20
+ function scopeKey(scope) {
21
+ return JSON.stringify([scope.ownerId, scope.channelId, scope.runtimeId, scope.sessionId, scope.generation]);
22
+ }
23
+ /** 所有异步任务共享额度;失效不等于内核 I/O 已停止或句柄已关闭。 */
24
+ export class FileReaderRuntime {
25
+ options;
26
+ resources = new Set();
27
+ opens = new Map();
28
+ idleMs;
29
+ maxResources;
30
+ timer;
31
+ timerDeadline;
32
+ disposed = false;
33
+ constructor(options) {
34
+ this.options = options;
35
+ this.idleMs = options.idleMs ?? DEFAULT_IDLE_MS;
36
+ this.maxResources = options.maxResources ?? DEFAULT_MAX_RESOURCES;
37
+ if (!Number.isFinite(this.idleMs) || this.idleMs <= 0 || !Number.isInteger(this.maxResources)
38
+ || this.maxResources < 1 || this.maxResources > DEFAULT_MAX_RESOURCES)
39
+ throw new Error("invalid reader limits");
40
+ }
41
+ get resourceCount() { return this.resources.size; }
42
+ reserve(scope, key, publicationId) {
43
+ if (this.disposed)
44
+ throw new FileAccessError("not_available");
45
+ if (this.resources.size >= this.maxResources || processLeases.size >= DEFAULT_MAX_RESOURCES)
46
+ throw new ReaderError("busy");
47
+ let reject;
48
+ const cancelled = new Promise((_, failure) => { reject = failure; });
49
+ // 没有请求等待的 idle 取消也不能制造 unhandled rejection。
50
+ void cancelled.catch(() => undefined);
51
+ const resource = {
52
+ scope: scope && { ...scope }, key, publicationId, transferId: randomUUID(), lease: Symbol(), hash: createHash("sha256"),
53
+ offset: 0, invalid: false, active: true, lastUsed: Date.now(), cancelled,
54
+ cancel: (code) => reject(new ReaderError(code)),
55
+ };
56
+ processLeases.add(resource.lease);
57
+ this.resources.add(resource);
58
+ if (key)
59
+ this.opens.set(key, resource);
60
+ this.schedule();
61
+ return resource;
62
+ }
63
+ schedule() {
64
+ const deadline = this.resources.size ? Math.min(...[...this.resources].map((resource) => resource.invalid
65
+ ? resource.retryAt : resource.lastUsed + this.idleMs)) : undefined;
66
+ if (this.timer && this.timerDeadline === deadline)
67
+ return;
68
+ if (this.timer)
69
+ clearTimeout(this.timer);
70
+ this.timer = undefined;
71
+ this.timerDeadline = deadline;
72
+ if (deadline === undefined)
73
+ return;
74
+ this.timer = setTimeout(() => {
75
+ this.timer = undefined;
76
+ this.timerDeadline = undefined;
77
+ const now = Date.now();
78
+ for (const resource of this.resources) {
79
+ if (resource.invalid ? resource.retryAt <= now : resource.lastUsed + this.idleMs <= now) {
80
+ this.invalidate(resource);
81
+ // 失效且底层 I/O 未结束或关闭失败时,不能按已过期 idle deadline 忙循环。
82
+ resource.retryAt = now + this.idleMs;
83
+ if (!resource.active)
84
+ void this.cleanup(resource);
85
+ }
86
+ }
87
+ this.schedule();
88
+ }, Math.max(1, deadline - Date.now()));
89
+ this.timer.unref?.();
90
+ }
91
+ invalidate(resource, code = "invalid_transfer") {
92
+ resource.invalid = true;
93
+ resource.retryAt ??= Date.now() + this.idleMs;
94
+ resource.cancel(code);
95
+ }
96
+ assertCurrent(resource) {
97
+ if (resource.invalid || this.disposed || (resource.scope && !this.options.isCurrent(resource.scope))) {
98
+ throw new ReaderError("invalid_transfer");
99
+ }
100
+ }
101
+ async eligible(resource) {
102
+ this.assertCurrent(resource);
103
+ if (!resource.scope || !resource.publicationId)
104
+ return;
105
+ const publication = await this.options.resolve(resource.scope, resource.publicationId);
106
+ this.assertCurrent(resource);
107
+ if (!publication)
108
+ throw new FileAccessError("not_available");
109
+ if (resource.path && publication.sourcePath !== resource.path)
110
+ throw new FileAccessError("file_changed");
111
+ if (!resource.path)
112
+ resource.path = publication.sourcePath;
113
+ }
114
+ async checked(resource, operation, policy = "publication") {
115
+ if (policy === "publication")
116
+ await this.eligible(resource);
117
+ this.assertCurrent(resource);
118
+ const result = await operation();
119
+ this.assertCurrent(resource);
120
+ if (policy === "publication")
121
+ await this.eligible(resource);
122
+ return result;
123
+ }
124
+ release(resource) {
125
+ if (resource.active || resource.handle || resource.closing)
126
+ return;
127
+ if (this.resources.delete(resource))
128
+ processLeases.delete(resource.lease);
129
+ if (resource.key && this.opens.get(resource.key) === resource)
130
+ this.opens.delete(resource.key);
131
+ this.schedule();
132
+ }
133
+ async closeHandle(resource) {
134
+ if (resource.closing)
135
+ return resource.closing;
136
+ if (!resource.handle)
137
+ return;
138
+ const handle = resource.handle;
139
+ resource.closing = handle.close().then(() => { resource.handle = undefined; });
140
+ try {
141
+ await resource.closing;
142
+ resource.closeFailed = false;
143
+ }
144
+ catch (error) {
145
+ resource.closeFailed = true;
146
+ resource.retryAt = Date.now() + this.idleMs;
147
+ if (resource.invalid)
148
+ this.schedule();
149
+ throw error;
150
+ }
151
+ finally {
152
+ resource.closing = undefined;
153
+ }
154
+ }
155
+ async cleanup(resource) {
156
+ try {
157
+ await this.closeHandle(resource);
158
+ }
159
+ catch { /* 保留真实句柄和额度,下次取消/idle/dispose 重试。 */ }
160
+ this.release(resource);
161
+ this.schedule();
162
+ }
163
+ async finish(resource) {
164
+ resource.active = false;
165
+ resource.lastUsed = Date.now();
166
+ if (resource.invalid && !resource.closeFailed)
167
+ await this.cleanup(resource);
168
+ else
169
+ this.release(resource);
170
+ this.schedule();
171
+ }
172
+ reply(frame, scope) {
173
+ return { protocol_version: 2, target_channel_id: scope.channelId, session_id: scope.sessionId, in_reply_to: frame.id };
174
+ }
175
+ failure(frame, scope, error) {
176
+ const code = error instanceof ReaderError ? error.code : errorCode(error);
177
+ return { ...this.reply(frame, scope), type: "file_error", code,
178
+ ...("transfer_id" in frame ? { transfer_id: frame.transfer_id } : {}) };
179
+ }
180
+ async handle(frame, suppliedScope) {
181
+ const scope = { ...suppliedScope };
182
+ try {
183
+ if (this.disposed || !this.options.isCurrent(scope))
184
+ throw new ReaderError("invalid_transfer");
185
+ if (frame.type === "file_open")
186
+ return await this.open(frame, scope);
187
+ const resource = [...this.resources].find((item) => item.transferId === frame.transfer_id
188
+ && item.scope && scopeKey(item.scope) === scopeKey(scope));
189
+ if (!resource)
190
+ throw new ReaderError("invalid_transfer");
191
+ if (frame.type === "file_close") {
192
+ this.invalidate(resource);
193
+ if (resource.active)
194
+ throw new ReaderError("busy");
195
+ await this.closeHandle(resource);
196
+ this.release(resource);
197
+ if (this.disposed || !this.options.isCurrent(scope))
198
+ throw new ReaderError("invalid_transfer");
199
+ return { ...this.reply(frame, scope), type: "file_closed", transfer_id: frame.transfer_id };
200
+ }
201
+ this.assertCurrent(resource);
202
+ if (resource.active)
203
+ throw new ReaderError("busy");
204
+ if (frame.offset !== resource.offset)
205
+ throw new ReaderError("offset_mismatch");
206
+ resource.active = true;
207
+ resource.lastUsed = Date.now();
208
+ this.schedule();
209
+ const response = await Promise.race([this.readTask(resource, frame, scope), resource.cancelled]);
210
+ if (response.type !== "file_error")
211
+ this.assertCurrent(resource);
212
+ return response;
213
+ }
214
+ catch (error) {
215
+ return this.failure(frame, scope, error);
216
+ }
217
+ }
218
+ async open(frame, scope) {
219
+ const key = `${scopeKey(scope)}:${JSON.stringify(frame.id)}`;
220
+ const existing = this.opens.get(key);
221
+ if (existing) {
222
+ if (existing.publicationId !== frame.publication_id)
223
+ throw new ReaderError("invalid_transfer");
224
+ this.assertCurrent(existing);
225
+ const replay = async () => {
226
+ await this.eligible(existing);
227
+ return existing.opened ?? await existing.pending;
228
+ };
229
+ return this.openResponse(existing, replay());
230
+ }
231
+ const resource = this.reserve(scope, key, frame.publication_id);
232
+ resource.pending = this.openTask(resource, frame, scope);
233
+ return this.openResponse(resource, resource.pending);
234
+ }
235
+ async openResponse(resource, pending) {
236
+ try {
237
+ const response = await Promise.race([pending, resource.cancelled]);
238
+ if (response.type !== "file_error") {
239
+ await Promise.race([this.eligible(resource), resource.cancelled]);
240
+ this.assertCurrent(resource);
241
+ }
242
+ resource.lastUsed = Date.now();
243
+ this.schedule();
244
+ return response;
245
+ }
246
+ catch (error) {
247
+ this.invalidate(resource, error instanceof ReaderError ? error.code : errorCode(error));
248
+ if (!resource.active && !resource.closeFailed)
249
+ void this.cleanup(resource);
250
+ throw error;
251
+ }
252
+ }
253
+ async openTask(resource, frame, scope) {
254
+ try {
255
+ await this.eligible(resource);
256
+ this.assertCurrent(resource);
257
+ const opened = await openSourceFile(resource.path, { resolveLinks: false, maxBytes: FILE_MAX_BYTES });
258
+ // 迟到句柄必须先入账,再检查失效,不能由 Promise.race 丢失所有权。
259
+ resource.handle = opened.handle;
260
+ resource.stat = opened.stat;
261
+ this.assertCurrent(resource);
262
+ await this.eligible(resource);
263
+ const fileName = basename(opened.path);
264
+ if (!fileName || fileName.length > 255 || /\p{Cc}/u.test(fileName))
265
+ throw new FileAccessError("not_available");
266
+ const inspection = await this.checked(resource, () => inspectFile(opened.handle, Number(opened.stat.size), fileName));
267
+ await this.verify(resource);
268
+ this.assertCurrent(resource);
269
+ resource.opened = { ...this.reply(frame, scope), type: "file_opened", publication_id: frame.publication_id,
270
+ transfer_id: resource.transferId, file_name: fileName, byte_length: Number(opened.stat.size),
271
+ mime_type: inspection.mimeType, preview: inspection.preview };
272
+ return resource.opened;
273
+ }
274
+ catch (error) {
275
+ if (error instanceof FileAccessError && error.handle) {
276
+ resource.handle = error.handle;
277
+ resource.closeFailed = true;
278
+ }
279
+ this.invalidate(resource, error instanceof ReaderError ? error.code : errorCode(error));
280
+ return this.failure(frame, scope, error);
281
+ }
282
+ finally {
283
+ await this.finish(resource);
284
+ }
285
+ }
286
+ async verify(resource, policy = "publication") {
287
+ const current = await this.checked(resource, () => resource.handle.stat({ bigint: true }), policy);
288
+ if (!sameFile(resource.stat, current))
289
+ throw new FileAccessError("file_changed");
290
+ // 对父路径逐层拒绝后来引入的链接;同一句柄属性检查不能替代路径身份检查。
291
+ let parent = dirname(resource.path);
292
+ const root = parse(parent).root;
293
+ while (true) {
294
+ const stat = await this.checked(resource, () => lstat(parent, { bigint: true }), policy);
295
+ if (!stat.isDirectory() || stat.isSymbolicLink())
296
+ throw new FileAccessError("file_changed");
297
+ if (parent === root)
298
+ break;
299
+ parent = dirname(parent);
300
+ }
301
+ try {
302
+ const atPath = await this.checked(resource, () => lstat(resource.path, { bigint: true }), policy);
303
+ if (atPath.isSymbolicLink() || !sameFile(resource.stat, atPath))
304
+ throw new FileAccessError("file_changed");
305
+ const canonical = await this.checked(resource, () => realpath(resource.path), policy);
306
+ if (canonical !== resource.path)
307
+ throw new FileAccessError("file_changed");
308
+ }
309
+ catch (error) {
310
+ if (typeof error === "object" && error !== null && "code" in error && ["ENOENT", "ENOTDIR", "ELOOP"].includes(String(error.code))) {
311
+ throw new FileAccessError("file_changed");
312
+ }
313
+ throw error;
314
+ }
315
+ }
316
+ async readTask(resource, frame, scope) {
317
+ try {
318
+ // 分支发布索引只在请求入口和响应出口重建;底层 I/O 仍逐次检查 scope 和磁盘身份。
319
+ await this.eligible(resource);
320
+ const response = await this.read(resource, frame, scope);
321
+ if (response.type !== "file_error")
322
+ await this.eligible(resource);
323
+ return response;
324
+ }
325
+ catch (error) {
326
+ this.invalidate(resource, error instanceof ReaderError ? error.code : errorCode(error));
327
+ return this.failure(frame, scope, error);
328
+ }
329
+ finally {
330
+ await this.finish(resource);
331
+ }
332
+ }
333
+ async read(resource, frame, scope) {
334
+ try {
335
+ await this.verify(resource, "scope");
336
+ const total = Number(resource.stat.size);
337
+ const data = Buffer.alloc(Math.min(FILE_CHUNK_BYTES, total - resource.offset));
338
+ let count = 0;
339
+ while (count < data.length) {
340
+ const result = await this.checked(resource, () => resource.handle.read(data, count, data.length - count, resource.offset + count), "scope");
341
+ if (!result.bytesRead)
342
+ throw new FileAccessError("file_changed");
343
+ count += result.bytesRead;
344
+ }
345
+ await this.verify(resource, "scope");
346
+ resource.hash.update(data);
347
+ resource.offset += data.length;
348
+ const common = { ...this.reply(frame, scope), type: "file_chunk", transfer_id: resource.transferId,
349
+ offset: frame.offset, data_base64: data.toString("base64") };
350
+ if (resource.offset !== total)
351
+ return { ...common, final: false };
352
+ const sha256 = resource.hash.digest("hex");
353
+ await this.checked(resource, () => this.closeHandle(resource), "scope");
354
+ this.assertCurrent(resource);
355
+ return { ...common, final: true, total_bytes: total, sha256 };
356
+ }
357
+ catch (error) {
358
+ this.invalidate(resource, error instanceof ReaderError ? error.code : errorCode(error));
359
+ return this.failure(frame, scope, error);
360
+ }
361
+ }
362
+ async inspectForPublication(path) {
363
+ const resource = this.reserve();
364
+ const task = this.inspectTask(resource, path);
365
+ return Promise.race([task, resource.cancelled]);
366
+ }
367
+ async inspectTask(resource, path) {
368
+ try {
369
+ this.assertCurrent(resource);
370
+ const opened = await openSourceFile(path, { resolveLinks: true, maxBytes: FILE_MAX_BYTES });
371
+ resource.handle = opened.handle;
372
+ resource.path = opened.path;
373
+ resource.stat = opened.stat;
374
+ this.assertCurrent(resource);
375
+ const fileName = basename(opened.path);
376
+ if (!fileName || fileName.length > 255 || /\p{Cc}/u.test(fileName))
377
+ throw new FileAccessError("not_available");
378
+ const inspection = await this.checked(resource, () => inspectFile(opened.handle, Number(opened.stat.size), fileName));
379
+ await this.verify(resource);
380
+ await this.checked(resource, () => this.closeHandle(resource));
381
+ return { sourcePath: opened.path, fileName, mimeType: inspection.mimeType, byteLength: Number(opened.stat.size) };
382
+ }
383
+ catch (error) {
384
+ if (error instanceof FileAccessError && error.handle) {
385
+ resource.handle = error.handle;
386
+ resource.closeFailed = true;
387
+ }
388
+ this.invalidate(resource, error instanceof ReaderError ? error.code : errorCode(error));
389
+ throw error;
390
+ }
391
+ finally {
392
+ await this.finish(resource);
393
+ }
394
+ }
395
+ async closeWhere(predicate) {
396
+ const matches = [...this.resources].filter((resource) => resource.scope && predicate({ ...resource.scope }));
397
+ for (const resource of matches)
398
+ this.invalidate(resource);
399
+ await Promise.all(matches.filter((resource) => !resource.active).map((resource) => this.cleanup(resource)));
400
+ }
401
+ async dispose() {
402
+ this.disposed = true;
403
+ const resources = [...this.resources];
404
+ for (const resource of resources)
405
+ this.invalidate(resource);
406
+ await Promise.all(resources.filter((resource) => !resource.active).map((resource) => this.cleanup(resource)));
407
+ }
408
+ }
409
+ class ReaderError extends Error {
410
+ code;
411
+ constructor(code) {
412
+ super(code);
413
+ this.code = code;
414
+ }
415
+ }
416
+ //# sourceMappingURL=reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reader.js","sourceRoot":"","sources":["../../src/files/reader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { type BigIntStats } from "node:fs";
2
+ import { type FileHandle } from "node:fs/promises";
3
+ export type FileAccessCode = "not_available" | "permission_denied" | "not_regular_file" | "too_large" | "file_changed" | "io_error";
4
+ export declare class FileAccessError extends Error {
5
+ readonly code: FileAccessCode;
6
+ /** 仅当关闭失败时由调用者接管并重试回收;不能把该资源计作已释放。 */
7
+ handle?: FileHandle;
8
+ closeError?: unknown;
9
+ constructor(code: FileAccessCode);
10
+ }
11
+ /**
12
+ * 返回的句柄由调用者关闭。路径检查不提供原子文件快照;后续读取仍须核验同一句柄属性。
13
+ * NONBLOCK 防普通文件被 FIFO 替换时阻塞,不提供恶意文件系统内核 I/O 的硬取消。
14
+ */
15
+ export declare function openSourceFile(path: string, options: {
16
+ resolveLinks: boolean;
17
+ maxBytes: number;
18
+ }): Promise<{
19
+ handle: FileHandle;
20
+ path: string;
21
+ stat: BigIntStats;
22
+ }>;