@procedures/fs 0.27.1 → 0.27.3
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/CHANGELOG.md +23 -0
- package/README.md +63 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/files/atomic.d.ts +39 -0
- package/dist/files/atomic.d.ts.map +1 -0
- package/dist/files/atomic.js +164 -0
- package/dist/files/atomic.js.map +1 -0
- package/dist/files/edit.d.ts +36 -0
- package/dist/files/edit.d.ts.map +1 -0
- package/dist/files/edit.js +56 -0
- package/dist/files/edit.js.map +1 -0
- package/dist/files/index.d.ts +14 -0
- package/dist/files/index.d.ts.map +1 -0
- package/dist/files/index.js +14 -0
- package/dist/files/index.js.map +1 -0
- package/dist/files/lock.d.ts +72 -0
- package/dist/files/lock.d.ts.map +1 -0
- package/dist/files/lock.js +106 -0
- package/dist/files/lock.js.map +1 -0
- package/dist/files/ndjson-tail.d.ts +41 -0
- package/dist/files/ndjson-tail.d.ts.map +1 -0
- package/dist/files/ndjson-tail.js +104 -0
- package/dist/files/ndjson-tail.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +6 -2
- package/src/files/atomic.ts +179 -0
- package/src/files/edit.ts +98 -0
- package/src/files/index.ts +21 -0
- package/src/files/lock.ts +159 -0
- package/src/files/ndjson-tail.ts +124 -0
- package/src/index.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @procedures/fs
|
|
2
2
|
|
|
3
|
+
## 0.27.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 194cdfb: Four file helpers in the new entry `@procedures/fs/files` (roadmap O51). The package root exports them too.
|
|
8
|
+
|
|
9
|
+
PATCH: new exports before 1.0.0. No export or behavior changes.
|
|
10
|
+
|
|
11
|
+
- `writeFileAtomic(path, data, options?)` writes a temporary file in the folder of the target, flushes it and renames it over the target. After a failure, it removes the temporary file. The file keeps the permissions of the target, unless `mode` is set. On Windows, it tries the rename again after `EPERM`, `EACCES` or `EBUSY` for `renameRetryMs` (2000 by default), and it does not flush the folder.
|
|
12
|
+
- `healNdjsonTail(path, options?)` repairs the end of an append-only NDJSON file after a crash. It reads only the last line from the end. It cuts off a part of a line with `ftruncate`, and it adds the newline to a complete last record. It gives `{ action: "none" | "truncated" | "newline", bytes, size }`.
|
|
13
|
+
- `KeyedLock` and `withLock(key, fn, options?)` let one caller at a time hold a key in the process. The waiters get the key in the order of their calls. With `ifHeld: "skip"`, the call gives `{ ran: false }` when the key has a holder. A `signal` stops a wait. A key without a holder uses no memory.
|
|
14
|
+
- `editFile(path, transform, options?)` reads a file, waits for `transform` and writes the result with `writeFileAtomic()`, one edit at a time for each path. A missing file gives `initial` or `undefined`. The same text or `undefined` writes nothing.
|
|
15
|
+
|
|
16
|
+
jarvis has copies of these helpers since jarvis PR #85 (`TODO(@procedures)`). It can use the package after the release.
|
|
17
|
+
- @procedures/client@0.27.3
|
|
18
|
+
|
|
19
|
+
## 0.27.2
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies [7bc4c6d]
|
|
24
|
+
- @procedures/client@0.27.2
|
|
25
|
+
|
|
3
26
|
## 0.27.1
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -166,6 +166,68 @@ The entry `@procedures/fs/root` has the rules of the root without the procedures
|
|
|
166
166
|
- `createFsModule({ root })` and `confineFsProcedures()` confine only the `fs.*` procedures and their nested calls. `confineToRoot()` also confines or refuses the other procedures.
|
|
167
167
|
- The root does not replace the permissions of the operating system.
|
|
168
168
|
|
|
169
|
+
## File helpers
|
|
170
|
+
|
|
171
|
+
The entry `@procedures/fs/files` has four functions for the files of an app. They are not procedures, and an import of the entry registers nothing. The package root exports them too.
|
|
172
|
+
|
|
173
|
+
### `writeFileAtomic(path, data, options?)`
|
|
174
|
+
|
|
175
|
+
The function writes a temporary file next to the target, flushes it to the disk and renames it over the target. A reader sees the old file or the whole new file.
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
import { writeFileAtomic } from "@procedures/fs/files";
|
|
179
|
+
|
|
180
|
+
await writeFileAtomic("./state.json", JSON.stringify(state));
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
- After a failure, the function removes the temporary file.
|
|
184
|
+
- The file keeps the permissions of the target. The option `mode` sets other permissions.
|
|
185
|
+
- On Windows, an open handle of the target blocks the rename. The function tries again for `renameRetryMs` (2000 by default).
|
|
186
|
+
|
|
187
|
+
### `healNdjsonTail(path, options?)`
|
|
188
|
+
|
|
189
|
+
The function repairs the end of an append-only NDJSON file after a crash. Start it before the next append.
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
import { healNdjsonTail } from "@procedures/fs/files";
|
|
193
|
+
|
|
194
|
+
const { action, bytes } = await healNdjsonTail("./events.ndjson");
|
|
195
|
+
// "none", "truncated" (a part of a line is cut off) or "newline" (a complete record gets its newline)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
- The function reads only the last line, from the end of the file, up to `maxLineBytes` (16 MiB by default).
|
|
199
|
+
- A missing file and an empty file get no change.
|
|
200
|
+
|
|
201
|
+
### `withLock(key, fn, options?)` and `KeyedLock`
|
|
202
|
+
|
|
203
|
+
One caller at a time holds a key in the process. The other callers wait in the order of their calls. With `ifHeld: "skip"`, the call does not start `fn` when the key has a holder.
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
import { withLock } from "@procedures/fs/files";
|
|
207
|
+
|
|
208
|
+
const report = await withLock("morning", () => runMorning());
|
|
209
|
+
const outcome = await withLock("morning", () => runMorning(), { ifHeld: "skip" });
|
|
210
|
+
if (!outcome.ran) console.log("A morning is running.");
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
- The lock gives the key back when `fn` throws.
|
|
214
|
+
- The option `signal` stops a wait.
|
|
215
|
+
- `new KeyedLock()` has keys of its own, with `acquire()`, `tryAcquire()` and `run()`.
|
|
216
|
+
|
|
217
|
+
### `editFile(path, transform, options?)`
|
|
218
|
+
|
|
219
|
+
The function reads a file, waits for `transform` and writes the result with `writeFileAtomic()`. The edits of one path run one at a time in the process.
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
import { editFile } from "@procedures/fs/files";
|
|
223
|
+
|
|
224
|
+
await editFile("./.env", (text) => `${text}TOKEN=abc\n`, { initial: "" });
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
- A missing file gives `initial`, or `undefined` without it.
|
|
228
|
+
- A transform that gives the same text or `undefined` writes nothing.
|
|
229
|
+
- On Windows, the lock ignores the case of the letters of the path.
|
|
230
|
+
|
|
169
231
|
## API Reference
|
|
170
232
|
|
|
171
233
|
### File Operations
|
|
@@ -943,6 +1005,7 @@ client-fs/
|
|
|
943
1005
|
│ ├── root.ts # The check of a path against the root (the ./root entry)
|
|
944
1006
|
│ ├── handlers.ts # The handlers with a root
|
|
945
1007
|
│ ├── confine.ts # The root for the other procedures of a registry
|
|
1008
|
+
│ ├── files/ # The file helpers (the ./files entry): atomic write, NDJSON tail, lock, edit
|
|
946
1009
|
│ ├── procedures/
|
|
947
1010
|
│ │ ├── fs.ts # Barrel export
|
|
948
1011
|
│ │ └── fs/
|