@statewalker/webrun-files-sqlite 0.10.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/LICENSE +21 -0
- package/README.md +212 -0
- package/dist/blocks/byte-reader.d.ts +19 -0
- package/dist/blocks/byte-reader.d.ts.map +1 -0
- package/dist/blocks/sha256.d.ts +11 -0
- package/dist/blocks/sha256.d.ts.map +1 -0
- package/dist/blocks/sqlite-files-api.d.ts +61 -0
- package/dist/blocks/sqlite-files-api.d.ts.map +1 -0
- package/dist/blocks/stream-codec.d.ts +40 -0
- package/dist/blocks/stream-codec.d.ts.map +1 -0
- package/dist/bytes.d.ts +3 -0
- package/dist/bytes.d.ts.map +1 -0
- package/dist/cjs/index.cjs +1264 -0
- package/dist/codec.d.ts +47 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/drivers.d.ts +73 -0
- package/dist/drivers.d.ts.map +1 -0
- package/dist/esm/index.js +1253 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/sql.types.d.ts +25 -0
- package/dist/sql.types.d.ts.map +1 -0
- package/dist/sqlar-files-api.d.ts +52 -0
- package/dist/sqlar-files-api.d.ts.map +1 -0
- package/package.json +52 -0
- package/src/blocks/byte-reader.ts +64 -0
- package/src/blocks/sha256.ts +116 -0
- package/src/blocks/sqlite-files-api.ts +587 -0
- package/src/blocks/stream-codec.ts +132 -0
- package/src/bytes.ts +8 -0
- package/src/codec.ts +88 -0
- package/src/drivers.ts +133 -0
- package/src/index.ts +25 -0
- package/src/sql.types.ts +25 -0
- package/src/sqlar-files-api.ts +413 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022-2026 statewalker
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# @statewalker/webrun-files-sqlite
|
|
2
|
+
|
|
3
|
+
Two `FilesApi` implementations over SQLite, sharing one small SQL port with drivers for
|
|
4
|
+
`node:sqlite`, Cloudflare Durable Object storage and Cloudflare D1.
|
|
5
|
+
|
|
6
|
+
| | `SqliteFilesApi` | `SqlarFilesApi` |
|
|
7
|
+
| --- | --- | --- |
|
|
8
|
+
| Storage | paths → contents → blocks of ≤ 1 MiB | one row per file, [SQLite Archive](https://sqlite.org/sqlar.html) format |
|
|
9
|
+
| File size | unbounded; streamed block by block | one blob, read and written whole |
|
|
10
|
+
| Durable Objects / D1 | yes — every row stays under the 2 MB limit | only files whose stored row is under 2 MB |
|
|
11
|
+
| Readable by `sqlite3 -A` | no | yes |
|
|
12
|
+
| Identical content | stored once, shared by every path | stored per path |
|
|
13
|
+
|
|
14
|
+
Use `SqliteFilesApi` by default, and `SqlarFilesApi` where the archive must be portable to other
|
|
15
|
+
SQLAR tools, in a runtime without a row limit (Node, Deno, Bun, a browser SQLite).
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @statewalker/webrun-files-sqlite @statewalker/webrun-files
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`pako` is not a dependency: pass the module to `pakoCodec` / `pakoDeflateCodec` if you use them.
|
|
24
|
+
|
|
25
|
+
## Drivers
|
|
26
|
+
|
|
27
|
+
Both implementations take a `SqlDriver`. The package imports none of the handles below — they are
|
|
28
|
+
passed in — so it bundles for any runtime.
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { D1SqlDriver, DoSqlDriver, NodeSqlDriver } from "@statewalker/webrun-files-sqlite";
|
|
32
|
+
|
|
33
|
+
new NodeSqlDriver(new DatabaseSync("files.db")); // node:sqlite
|
|
34
|
+
new DoSqlDriver(this.ctx.storage); // inside a Durable Object: ctx.storage, not ctx.storage.sql
|
|
35
|
+
new D1SqlDriver(env.DB); // a D1 binding
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Any other SQLite binding works by implementing the port:
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
interface SqlStatement {
|
|
42
|
+
sql: string;
|
|
43
|
+
params?: unknown[];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface SqlDriver {
|
|
47
|
+
/** Rows as objects keyed by column name. */
|
|
48
|
+
all<T>(sql: string, ...params: unknown[]): T[] | Promise<T[]>;
|
|
49
|
+
/** One statement, for its effect. */
|
|
50
|
+
run(sql: string, ...params: unknown[]): void | Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* The statements in order, as one transaction: all apply or none do. Returns the number of rows
|
|
53
|
+
* each statement changed. No statement may depend on another's result.
|
|
54
|
+
*/
|
|
55
|
+
transaction(statements: SqlStatement[]): number[] | Promise<number[]>;
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The built-in drivers implement `transaction` with `BEGIN IMMEDIATE … COMMIT` (node:sqlite),
|
|
60
|
+
`ctx.storage.transactionSync` (Durable Objects, where `sql.exec` rejects `BEGIN`) and `batch()` (D1).
|
|
61
|
+
Blobs come back as `Uint8Array`, `ArrayBuffer` or `number[]` depending on the runtime; both
|
|
62
|
+
implementations accept all three.
|
|
63
|
+
|
|
64
|
+
## SqliteFilesApi
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { DatabaseSync } from "node:sqlite";
|
|
68
|
+
import { NodeSqlDriver, SqliteFilesApi } from "@statewalker/webrun-files-sqlite";
|
|
69
|
+
|
|
70
|
+
const files = new SqliteFilesApi(new NodeSqlDriver(new DatabaseSync("files.db")));
|
|
71
|
+
await files.init(); // creates fs_paths, fs_files and fs_blocks if missing
|
|
72
|
+
|
|
73
|
+
await files.write("/video.mp4", response.body); // any Iterable or AsyncIterable of Uint8Array
|
|
74
|
+
for await (const chunk of files.read("/video.mp4", { start: 10_000_000, length: 65_536 })) {
|
|
75
|
+
// only the block holding this range is fetched and inflated
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`init()` creates the tables and indexes if they are missing; await it before any other call.
|
|
80
|
+
|
|
81
|
+
### How content is stored
|
|
82
|
+
|
|
83
|
+
- `fs_paths(pid, path UNIQUE, fid, mtime)` — a path points at a content, or is a directory (`fid` NULL).
|
|
84
|
+
- `fs_files(fid, size, compression, block_size, hash, updated)` — an immutable content: its
|
|
85
|
+
uncompressed size, `"none"` or `"deflate"`, the block size it was written with, the SHA-256 of its
|
|
86
|
+
bytes, and when it last changed (`size` and `hash` are NULL while it is being written).
|
|
87
|
+
- `fs_blocks(fid, shift, block)`, keyed by `(fid, shift)` — the content cut into blocks of
|
|
88
|
+
`block_size` uncompressed bytes (only the last one shorter); `shift` is the block's offset in the
|
|
89
|
+
uncompressed content, always a multiple of `block_size`. Each block of a `deflate` content is its
|
|
90
|
+
own zlib stream, so a range read fetches and inflates exactly the blocks the range touches, found
|
|
91
|
+
by key.
|
|
92
|
+
|
|
93
|
+
`copy` adds path rows pointing at the same content; a write whose bytes match an existing content
|
|
94
|
+
(same SHA-256, size, compression and block size) shares it too. A content and its blocks are deleted when the
|
|
95
|
+
last path pointing at it is removed or overwritten.
|
|
96
|
+
|
|
97
|
+
### Streaming
|
|
98
|
+
|
|
99
|
+
`write` pulls the source only while it builds the current block and stores each block before
|
|
100
|
+
pulling for the next; `read` fetches a block only when its consumer asks for bytes beyond the
|
|
101
|
+
previous one. Memory is bounded by one block plus one source chunk, and the tests measure both
|
|
102
|
+
bounds. An `AbortSignal` passed to `read` is checked before every block.
|
|
103
|
+
|
|
104
|
+
`list` is streamed too: it reads `fs_paths` in pages of 256 by key, in the index's order — which is
|
|
105
|
+
the path order every `FilesApi` lists in — and `{ after }` is simply where the first page starts.
|
|
106
|
+
|
|
107
|
+
### Options
|
|
108
|
+
|
|
109
|
+
| Option | Default | |
|
|
110
|
+
| --- | --- | --- |
|
|
111
|
+
| `compression` | `webDeflateCodec()` where `CompressionStream` exists, else none | `null` stores uncompressed; `pakoDeflateCodec(pako)` for runtimes without Compression Streams |
|
|
112
|
+
| `tablePrefix` | `"fs_"` | several file systems in one database |
|
|
113
|
+
| `blockSize` | 1 MiB | uncompressed bytes per block for new writes, 1 to 1.5 MiB (the cap keeps a deflated block under the 2 MB row limit). Larger means fewer rows — better where statements are costly, as on D1; smaller means cheaper small range reads. Each content records its own size, so changing this never affects existing files. |
|
|
114
|
+
|
|
115
|
+
### Semantics worth knowing
|
|
116
|
+
|
|
117
|
+
- `copy` and `move` replace the target's subtree rather than merging into it, and throw when one
|
|
118
|
+
path contains the other.
|
|
119
|
+
- A write is invisible until complete: if it fails for any reason, the path keeps its previous
|
|
120
|
+
content and the partly written content is deleted.
|
|
121
|
+
- A read whose content is removed underneath it throws `changed during read`. A block whose
|
|
122
|
+
uncompressed length is not what its position implies throws `block at <shift> holds … bytes`,
|
|
123
|
+
before any wrong byte reaches the reader.
|
|
124
|
+
|
|
125
|
+
### Interruptions and `sweep`
|
|
126
|
+
|
|
127
|
+
Streaming happens outside transactions; every step that changes what a path shows is one
|
|
128
|
+
transaction (`BEGIN IMMEDIATE` on node:sqlite, `transactionSync` on Durable Objects, `batch()` on D1):
|
|
129
|
+
storing each block, finishing a write, `remove`, `copy` and `move`. A failure inside any of them
|
|
130
|
+
leaves the database exactly as it was — `move` onto an existing target never loses the target.
|
|
131
|
+
|
|
132
|
+
A write stays invisible until it finishes. If the process dies mid-stream, the partly written
|
|
133
|
+
content is left behind unreferenced; remove such leftovers with
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
const removed = await files.sweep({ olderThan: 60 * 60_000 }); // contents untouched for an hour
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`sweep` deletes contents that no path references and that have not been updated for `olderThan`
|
|
140
|
+
milliseconds, with their blocks. A write refreshes its content with every block, so only a write
|
|
141
|
+
stalled longer than `olderThan` can be swept — and it then fails rather than creating a broken path.
|
|
142
|
+
Choose a threshold above the longest pause a source may take. `sweep` never runs on its own.
|
|
143
|
+
|
|
144
|
+
## SqlarFilesApi
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
import { DatabaseSync } from "node:sqlite";
|
|
148
|
+
import { readText, writeText } from "@statewalker/webrun-files";
|
|
149
|
+
import { NodeSqlDriver, SqlarFilesApi } from "@statewalker/webrun-files-sqlite";
|
|
150
|
+
|
|
151
|
+
const files = new SqlarFilesApi(new NodeSqlDriver(new DatabaseSync("site.sqlar")));
|
|
152
|
+
await files.init(); // creates the sqlar table if missing — await before anything else
|
|
153
|
+
|
|
154
|
+
await writeText(files, "/docs/index.md", "# Hello");
|
|
155
|
+
console.log(await readText(files, "/docs/index.md"));
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
It takes the same drivers (see *Drivers*), subject to the row limit below.
|
|
159
|
+
|
|
160
|
+
### Compression codecs
|
|
161
|
+
|
|
162
|
+
| Codec | Uses | When |
|
|
163
|
+
| --- | --- | --- |
|
|
164
|
+
| `webCodec()` | `CompressionStream("deflate")` | Default wherever `CompressionStream` exists |
|
|
165
|
+
| `pakoCodec(pako, { level })` | an injected `pako` module | Runtimes without Compression Streams |
|
|
166
|
+
| `rawCodec()` | nothing | Default elsewhere; never compresses, and refuses to read compressed rows |
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
import * as pako from "pako";
|
|
170
|
+
const files = new SqlarFilesApi(driver, { codec: pakoCodec(pako) });
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
All codecs read and write the same zlib format, so an archive written with one is read by another.
|
|
174
|
+
Inputs shorter than `minSize` (64 bytes by default) are stored without attempting compression.
|
|
175
|
+
|
|
176
|
+
### How entries are stored
|
|
177
|
+
|
|
178
|
+
| Entry | `name` | `sz` | `data` |
|
|
179
|
+
| --- | --- | --- | --- |
|
|
180
|
+
| File | `docs/index.md` (no leading slash) | byte length | plaintext, or deflated when strictly shorter |
|
|
181
|
+
| Empty file | | `0` | zero-length blob |
|
|
182
|
+
| Directory | | `0` | `NULL` |
|
|
183
|
+
| Symlink | | `-1` | target as text |
|
|
184
|
+
|
|
185
|
+
`mtime` is stored in seconds; `lastModified` reports it in milliseconds. Archives written by other
|
|
186
|
+
tools without directory rows still behave as trees: a path that is only a prefix of other names is a
|
|
187
|
+
directory.
|
|
188
|
+
|
|
189
|
+
#### Symlinks
|
|
190
|
+
|
|
191
|
+
`FileKind` has no symlink, so `stats`, `exists`, `read` and `list` follow links the way POSIX
|
|
192
|
+
`stat()` does. A dangling link, or a chain of more than 8, behaves as a missing path. `remove`,
|
|
193
|
+
`copy` and `move` act on the link itself. Two extension methods give access to links:
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
await files.symlink("/latest.js", "./v2/index.js");
|
|
197
|
+
await files.readlink("/latest.js"); // "./v2/index.js"
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Limitations
|
|
201
|
+
|
|
202
|
+
- A file is one blob: `write` buffers its content, `read` inflates it whole and yields one chunk.
|
|
203
|
+
- On Durable Objects and D1 a row may not exceed 2 MB, so the *stored* (possibly compressed) size
|
|
204
|
+
of one file is capped there. Use `SqliteFilesApi` in those runtimes.
|
|
205
|
+
- Multi-row mutations (`copy`, `move`, `remove` of a tree) are not wrapped in a transaction.
|
|
206
|
+
- Only the final path component is resolved through symlinks.
|
|
207
|
+
- `list` loads every row under the directory, then sorts the entries into path order (implicit
|
|
208
|
+
directories and resolved links do not sit where the rows do) before applying `after`.
|
|
209
|
+
|
|
210
|
+
## License
|
|
211
|
+
|
|
212
|
+
MIT
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pull bytes from a chunk source in bounded pieces.
|
|
3
|
+
*
|
|
4
|
+
* `read(max)` hands out at most `max` bytes as a zero-copy view of the current
|
|
5
|
+
* source chunk, and pulls the next chunk only when the current one is spent.
|
|
6
|
+
* The source is therefore never read ahead of its consumer: this is the
|
|
7
|
+
* backpressure boundary between a caller's stream and block storage.
|
|
8
|
+
*/
|
|
9
|
+
export declare class ByteReader {
|
|
10
|
+
#private;
|
|
11
|
+
constructor(source: Iterable<Uint8Array> | AsyncIterable<Uint8Array>);
|
|
12
|
+
/** At most `max` bytes, or `undefined` once the source is exhausted. */
|
|
13
|
+
read(max: number): Promise<Uint8Array | undefined>;
|
|
14
|
+
/** Release the source early, as `break` in a `for await` would. */
|
|
15
|
+
close(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
/** One Uint8Array from a stream's chunks — only ever used on a single block's worth. */
|
|
18
|
+
export declare function collectBlock(chunks: AsyncIterable<Uint8Array>): Promise<Uint8Array>;
|
|
19
|
+
//# sourceMappingURL=byte-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"byte-reader.d.ts","sourceRoot":"","sources":["../../src/blocks/byte-reader.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,qBAAa,UAAU;;IAKrB,YAAY,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC,EAKnE;IAED,wEAAwE;IAClE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAcvD;IAED,mEAAmE;IAC7D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAK3B;CACF;AAED,wFAAwF;AACxF,wBAAsB,YAAY,CAAC,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAgBzF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incremental SHA-256 (FIPS 180-4). WebCrypto only hashes a whole buffer, and
|
|
3
|
+
* content here arrives as a stream it must never be collected from.
|
|
4
|
+
*/
|
|
5
|
+
export declare class Sha256 {
|
|
6
|
+
#private;
|
|
7
|
+
update(bytes: Uint8Array): this;
|
|
8
|
+
/** Finalises the hash; the instance cannot be used afterwards. */
|
|
9
|
+
digestHex(): string;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=sha256.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sha256.d.ts","sourceRoot":"","sources":["../../src/blocks/sha256.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,qBAAa,MAAM;;IAUjB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAmB9B;IAED,kEAAkE;IAClE,SAAS,IAAI,MAAM,CAalB;CAsDF"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { FileInfo, FileStats, FilesApi, ListOptions, ReadOptions } from "@statewalker/webrun-files";
|
|
2
|
+
import type { SqlDriver } from "../sql.types.js";
|
|
3
|
+
import { type StreamCodec } from "./stream-codec.js";
|
|
4
|
+
export interface SqliteFilesApiOptions {
|
|
5
|
+
/** Prefix of the three table names. Defaults to "fs_". */
|
|
6
|
+
tablePrefix?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Codec for new writes; `null` stores content uncompressed. Defaults to
|
|
9
|
+
* {@link webDeflateCodec} where Compression Streams exist, uncompressed elsewhere.
|
|
10
|
+
*/
|
|
11
|
+
compression?: StreamCodec | null;
|
|
12
|
+
/**
|
|
13
|
+
* Uncompressed bytes per block for new writes; only a file's last block is
|
|
14
|
+
* shorter. An integer from 1 to 1.5 MiB, default 1 MiB. Each content records
|
|
15
|
+
* the size it was written with, so changing this never affects existing files.
|
|
16
|
+
*/
|
|
17
|
+
blockSize?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A FilesApi over three SQLite tables: paths point at immutable contents, and
|
|
21
|
+
* a content is a sequence of bounded, optionally compressed blocks. Reads and
|
|
22
|
+
* writes stream one block at a time, so no file is ever held whole and no row
|
|
23
|
+
* outgrows the 2 MB limit of Durable Objects and D1.
|
|
24
|
+
*
|
|
25
|
+
* Streaming happens outside transactions; every step that changes what a path
|
|
26
|
+
* shows is one transaction, so an interruption leaves at most an unreferenced
|
|
27
|
+
* content, which {@link sweep} removes.
|
|
28
|
+
*/
|
|
29
|
+
export declare class SqliteFilesApi implements FilesApi {
|
|
30
|
+
#private;
|
|
31
|
+
constructor(sql: SqlDriver, opts?: SqliteFilesApiOptions);
|
|
32
|
+
/** Creates the tables and indexes if missing. Await it before any other call. */
|
|
33
|
+
init(): Promise<void>;
|
|
34
|
+
read(path: string, options?: ReadOptions): AsyncIterable<Uint8Array>;
|
|
35
|
+
/**
|
|
36
|
+
* Streams the content into a new, invisible content row, one block per
|
|
37
|
+
* transaction, then points the path at it in one transaction. Any failure
|
|
38
|
+
* removes the pending content; a crash leaves it for {@link sweep}.
|
|
39
|
+
*/
|
|
40
|
+
write(path: string, content: Iterable<Uint8Array> | AsyncIterable<Uint8Array>): Promise<void>;
|
|
41
|
+
mkdir(path: string): Promise<void>;
|
|
42
|
+
stats(path: string): Promise<FileStats | undefined>;
|
|
43
|
+
exists(path: string): Promise<boolean>;
|
|
44
|
+
list(path: string, options?: ListOptions): AsyncIterable<FileInfo>;
|
|
45
|
+
remove(path: string): Promise<boolean>;
|
|
46
|
+
copy(source: string, target: string): Promise<boolean>;
|
|
47
|
+
move(source: string, target: string): Promise<boolean>;
|
|
48
|
+
/**
|
|
49
|
+
* Deletes, in one transaction, every content not updated for `olderThan`
|
|
50
|
+
* milliseconds that is still pending or that no path references, with its
|
|
51
|
+
* blocks. Returns how many contents were deleted.
|
|
52
|
+
*
|
|
53
|
+
* A write refreshes its pending content with every block, so only a write
|
|
54
|
+
* stalled longer than `olderThan` can be swept — and it then fails instead of
|
|
55
|
+
* pointing a path at missing content. Never runs on its own.
|
|
56
|
+
*/
|
|
57
|
+
sweep(options: {
|
|
58
|
+
olderThan: number;
|
|
59
|
+
}): Promise<number>;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=sqlite-files-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-files-api.d.ts","sourceRoot":"","sources":["../../src/blocks/sqlite-files-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,WAAW,EACX,WAAW,EACZ,MAAM,2BAA2B,CAAC;AAGnC,OAAO,KAAK,EAAE,SAAS,EAAgB,MAAM,iBAAiB,CAAC;AAG/D,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,mBAAmB,CAAC;AAOtE,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAcD;;;;;;;;;GASG;AACH,qBAAa,cAAe,YAAW,QAAQ;;IAS7C,YAAY,GAAG,EAAE,SAAS,EAAE,IAAI,GAAE,qBAA0B,EAqB3D;IAED,iFAAiF;IAC3E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CA0B1B;IAIM,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,aAAa,CAAC,UAAU,CAAC,CA8C9E;IAID;;;;OAIG;IACG,KAAK,CACT,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC,GACxD,OAAO,CAAC,IAAI,CAAC,CAmEf;IA8CK,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASvC;IAIK,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAKxD;IAEK,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE3C;IAEM,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,aAAa,CAAC,QAAQ,CAAC,CA4B5E;IAIK,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAG3C;IAgCK,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE3D;IAEK,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE3D;IA6CD;;;;;;;;OAQG;IACG,KAAK,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAqB3D;CAiEF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A streaming compression format. Pulled, never pushed: `compress` and
|
|
3
|
+
* `decompress` read their input only as their output is consumed.
|
|
4
|
+
*/
|
|
5
|
+
export interface StreamCodec {
|
|
6
|
+
/** Stored in `fs_files.compression`. Implementations of one format share the name. */
|
|
7
|
+
name: string;
|
|
8
|
+
compress(input: AsyncIterable<Uint8Array>): AsyncIterable<Uint8Array>;
|
|
9
|
+
decompress(input: AsyncIterable<Uint8Array>): AsyncIterable<Uint8Array>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* zlib-wrapped Deflate over Compression Streams — browsers, Node, Deno, Bun,
|
|
13
|
+
* Workers. The source is wrapped in a pull-only ReadableStream, so the
|
|
14
|
+
* transform asks for input only when it has room, and cancelling the output
|
|
15
|
+
* closes the source.
|
|
16
|
+
*/
|
|
17
|
+
export declare function webDeflateCodec(): StreamCodec;
|
|
18
|
+
/** The part of the `pako` module the streaming codec uses. */
|
|
19
|
+
export interface PakoStreamModule {
|
|
20
|
+
Deflate: new (options?: {
|
|
21
|
+
level?: number;
|
|
22
|
+
}) => PakoStream;
|
|
23
|
+
Inflate: new () => PakoStream;
|
|
24
|
+
}
|
|
25
|
+
interface PakoStream {
|
|
26
|
+
push(data: Uint8Array, flush?: boolean): boolean;
|
|
27
|
+
onData(chunk: Uint8Array): void;
|
|
28
|
+
err: number;
|
|
29
|
+
msg: string;
|
|
30
|
+
ended?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* zlib-wrapped Deflate through pako's incremental classes, for runtimes without
|
|
34
|
+
* Compression Streams. The module is injected, not imported.
|
|
35
|
+
*/
|
|
36
|
+
export declare function pakoDeflateCodec(pako: PakoStreamModule, opts?: {
|
|
37
|
+
level?: number;
|
|
38
|
+
}): StreamCodec;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=stream-codec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-codec.d.ts","sourceRoot":"","sources":["../../src/blocks/stream-codec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,sFAAsF;IACtF,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;IACtE,UAAU,CAAC,KAAK,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;CACzE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,WAAW,CAW7C;AAED,8DAA8D;AAC9D,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,KAAK,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,UAAU,CAAC;IAC1D,OAAO,EAAE,UAAU,UAAU,CAAC;CAC/B;AAED,UAAU,UAAU;IAClB,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IACjD,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,gBAAgB,EACtB,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5B,WAAW,CAOb"}
|
package/dist/bytes.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bytes.d.ts","sourceRoot":"","sources":["../src/bytes.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAMlD"}
|