@statewalker/webrun-files-rpc 0.0.0-stage → 0.1.1

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/src/types.ts ADDED
@@ -0,0 +1,120 @@
1
+ import type { FileInfo, FileStats, FilesApi } from "@statewalker/webrun-files";
2
+
3
+ /** One chunk of a read stream: its bytes, and whether it is the last. */
4
+ export interface ReadResult {
5
+ data: Uint8Array;
6
+ done: boolean;
7
+ }
8
+
9
+ /** One page of a listing. `more`: ask again with `after` = the last path of this page. */
10
+ export interface ListPage {
11
+ entries: FileInfo[];
12
+ more: boolean;
13
+ }
14
+
15
+ /** One page of `list`: `after` the given path (exclusive), at most `limit` entries. */
16
+ export interface ListPageOptions {
17
+ recursive?: boolean;
18
+ after?: string;
19
+ limit?: number;
20
+ }
21
+
22
+ /** Open options shared by reads and writes. */
23
+ export interface OpenOptions {
24
+ /**
25
+ * The stream's id, chosen by the caller (16 to 128 characters of `[A-Za-z0-9_-]`, random:
26
+ * `crypto.randomUUID()`), so that an open delivered twice opens one stream. Without it the
27
+ * server chooses one.
28
+ */
29
+ streamId?: string;
30
+ }
31
+
32
+ /** Options of the calls that change metadata (`mkdir`, `remove`, `move`, `copy`). */
33
+ export interface RequestOptions {
34
+ /**
35
+ * The call's id, chosen by the caller (the same form as a stream id). The server keeps each
36
+ * id's answer for `idleTimeout` (at most `maxRequests` of them): the same call delivered again
37
+ * gets that answer and does not run again.
38
+ */
39
+ requestId?: string;
40
+ }
41
+
42
+ export interface OpenWriteOptions extends OpenOptions {
43
+ /**
44
+ * Add the stream's chunks to the end of the file instead of replacing it (a file that does not
45
+ * exist is created). See `AppendableFilesApi` for how the server appends.
46
+ */
47
+ append?: boolean;
48
+ }
49
+
50
+ /**
51
+ * A FilesApi that can append itself. `FilesApi` has no append; a served FilesApi with this method
52
+ * gets appends through it. Any other is appended to with read, write and remove only: the old
53
+ * content and the new chunks go to a temporary sibling (`.<name>.append-<streamId>`), which is
54
+ * then written back over the file and removed.
55
+ */
56
+ export interface AppendableFilesApi extends FilesApi {
57
+ append(path: string, content: AsyncIterable<Uint8Array>): Promise<void>;
58
+ }
59
+
60
+ export interface OpenReadOptions extends OpenOptions {
61
+ /** First byte (default 0). */
62
+ start?: number;
63
+ /** Bytes to read (default: to the end). */
64
+ length?: number;
65
+ }
66
+
67
+ /**
68
+ * What the server exposes and the client calls: a FilesApi cut into calls an RPC can carry.
69
+ * Every argument and result is a plain value (strings, numbers, booleans, plain objects,
70
+ * Uint8Array), so any transport that passes structured-clonable values carries it: Durable
71
+ * Object and Workers RPC, postMessage, comlink, or a direct call.
72
+ *
73
+ * Content moves as chunks keyed by (streamId, chunkId). chunkId counts from 0 in each stream.
74
+ * Both sides keep chunks by their key and wait for the ones that have not arrived: the server
75
+ * answers `readChunk(id, k)` once chunk k exists, and writes chunk k once chunks 0..k-1 are
76
+ * written, whatever order they came in. Calls delivered twice are harmless.
77
+ */
78
+ export interface FilesRpc {
79
+ stats(path: string): Promise<FileStats | undefined>;
80
+ exists(path: string): Promise<boolean>;
81
+ mkdir(path: string, options?: RequestOptions): Promise<void>;
82
+ remove(path: string, options?: RequestOptions): Promise<boolean>;
83
+ move(source: string, target: string, options?: RequestOptions): Promise<boolean>;
84
+ copy(source: string, target: string, options?: RequestOptions): Promise<boolean>;
85
+ list(path: string, options?: ListPageOptions): Promise<ListPage>;
86
+
87
+ /** Opens `path` for reading. A file that does not exist reads as nothing. */
88
+ openRead(path: string, options?: OpenReadOptions): Promise<{ streamId: string }>;
89
+ /**
90
+ * Chunk `chunkId` of the stream, once it exists. Past the end: empty and done. A chunk can be
91
+ * asked again (a retry) until the reader has moved `retain` chunks past it.
92
+ */
93
+ readChunk(streamId: string, chunkId: number): Promise<ReadResult>;
94
+ /** Ends the stream (unknown or closed: nothing happens). */
95
+ closeRead(streamId: string): Promise<void>;
96
+
97
+ /**
98
+ * Opens `path` for writing (or, with `append`, for appending); the FilesApi consumes the chunks
99
+ * in order.
100
+ */
101
+ openWrite(path: string, options?: OpenWriteOptions): Promise<{ streamId: string }>;
102
+ /**
103
+ * Hands over chunk `chunkId`. Resolves once it is kept (not yet written): at once if it is
104
+ * within `writeWindow` chunks of the next to write, else when it is. A chunk already received
105
+ * is ignored.
106
+ */
107
+ writeChunk(streamId: string, chunkId: number, data: Uint8Array | ArrayBuffer): Promise<void>;
108
+ /** The stream had `chunks` chunks: resolves when all of them are written. */
109
+ closeWrite(streamId: string, chunks: number): Promise<void>;
110
+ /** Cancels the write (unknown or closed: nothing happens). */
111
+ abortWrite(streamId: string, reason?: string): Promise<void>;
112
+ }
113
+
114
+ /** Error codes of FilesRpcError. */
115
+ export type FilesRpcErrorCode =
116
+ | "UNKNOWN_STREAM"
117
+ | "CHUNK_RELEASED"
118
+ | "TOO_MANY_STREAMS"
119
+ | "ABORTED"
120
+ | "INVALID";