@phreshos/node 0.1.12 → 0.1.13

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/dist/uploads.d.ts CHANGED
@@ -3,8 +3,10 @@ type Ask = (request: object) => Promise<unknown>;
3
3
  /** Owner-local implementation of the System's opaque upload collection. */
4
4
  export default class Uploads implements SystemUploads {
5
5
  private readonly ask;
6
+ private readonly lifetime;
6
7
  private accessPromise;
7
- constructor(ask: Ask);
8
+ constructor(ask: Ask, lifetime: () => AbortSignal);
9
+ path(): Promise<string>;
8
10
  write(value: unknown): Promise<Upload>;
9
11
  stream(file: string): Promise<ReadableStream<Uint8Array<ArrayBufferLike>>>;
10
12
  bytes(file: string): Promise<Uint8Array<ArrayBuffer>>;
@@ -17,5 +19,6 @@ export default class Uploads implements SystemUploads {
17
19
  time: number;
18
20
  }> | null>;
19
21
  private access;
22
+ private active;
20
23
  }
21
24
  export {};
package/dist/uploads.js CHANGED
@@ -2,17 +2,23 @@ import { isUploadFile } from "@phreshos/core";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { createReadStream, createWriteStream, mkdirSync } from "node:fs";
4
4
  import { rename, rm } from "node:fs/promises";
5
- import { join } from "node:path";
5
+ import { isAbsolute, join } from "node:path";
6
6
  import { Readable } from "node:stream";
7
7
  import { pipeline } from "node:stream/promises";
8
8
  /** Owner-local implementation of the System's opaque upload collection. */
9
9
  export default class Uploads {
10
10
  ask;
11
+ lifetime;
11
12
  accessPromise = null;
12
- constructor(ask) {
13
+ constructor(ask, lifetime) {
13
14
  this.ask = ask;
15
+ this.lifetime = lifetime;
16
+ }
17
+ async path() {
18
+ return (await this.access()).path;
14
19
  }
15
20
  async write(value) {
21
+ const signal = this.active();
16
22
  const access = await this.access();
17
23
  const source = content(value);
18
24
  const identity = randomUUID();
@@ -29,7 +35,8 @@ export default class Uploads {
29
35
  throw new Error(`The upload exceeds ${access.limit / 1024 / 1024 / 1024} GB`);
30
36
  yield chunk;
31
37
  }
32
- }, createWriteStream(temporary, { flags: "wx" }));
38
+ }, createWriteStream(temporary, { flags: "wx" }), { signal });
39
+ signal.throwIfAborted();
33
40
  await rename(temporary, destination);
34
41
  }
35
42
  catch (error) {
@@ -42,22 +49,25 @@ export default class Uploads {
42
49
  return upload;
43
50
  }
44
51
  async stream(file) {
52
+ const signal = this.active();
45
53
  requireFile(file);
46
54
  const access = await this.access();
47
- return Readable.toWeb(createReadStream(join(access.path, file)));
55
+ return Readable.toWeb(createReadStream(join(access.path, file), { signal }));
48
56
  }
49
57
  async bytes(file) { return new Uint8Array(await new Response(await this.stream(file)).arrayBuffer()); }
50
58
  async text(file) { return new Response(await this.stream(file)).text(); }
51
59
  async json(file) { return JSON.parse(await this.text(file)); }
52
60
  async stat(file) {
61
+ this.active();
53
62
  requireFile(file);
54
63
  return await this.ask({ capability: "uploads", operation: "stat", file });
55
64
  }
56
65
  access() {
66
+ this.active();
57
67
  if (!this.accessPromise) {
58
68
  const resolving = this.ask({ capability: "uploads", operation: "access" }).then(value => {
59
69
  const access = value;
60
- if (!access || typeof access.path !== "string" || typeof access.limit !== "number")
70
+ if (!access || typeof access.path !== "string" || !isAbsolute(access.path) || typeof access.limit !== "number")
61
71
  throw new Error("The System returned invalid upload access");
62
72
  return { path: access.path, limit: access.limit };
63
73
  });
@@ -70,6 +80,11 @@ export default class Uploads {
70
80
  }
71
81
  return this.accessPromise;
72
82
  }
83
+ active() {
84
+ const signal = this.lifetime();
85
+ signal.throwIfAborted();
86
+ return signal;
87
+ }
73
88
  }
74
89
  function requireFile(file) {
75
90
  if (!isUploadFile(file))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phreshos/node",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "Node.js access to PhreshOS and Program projects.",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",
@@ -36,7 +36,7 @@
36
36
  "prepack": "node --run build"
37
37
  },
38
38
  "dependencies": {
39
- "@phreshos/core": "^0.1.36",
39
+ "@phreshos/core": "^0.1.37",
40
40
  "adm-zip": "^0.6.0",
41
41
  "jiti": "^2.7.0"
42
42
  },