@zenfs/core 2.2.2 → 2.3.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.
Files changed (60) hide show
  1. package/dist/backends/backend.js +6 -9
  2. package/dist/backends/cow.js +4 -4
  3. package/dist/backends/fetch.js +8 -6
  4. package/dist/backends/memory.js +4 -2
  5. package/dist/backends/passthrough.js +2 -0
  6. package/dist/backends/port.d.ts +16 -89
  7. package/dist/backends/port.js +35 -171
  8. package/dist/backends/single_buffer.d.ts +4 -2
  9. package/dist/backends/single_buffer.js +169 -195
  10. package/dist/backends/store/fs.js +50 -73
  11. package/dist/backends/store/map.js +1 -2
  12. package/dist/backends/store/store.js +23 -27
  13. package/dist/config.js +2 -3
  14. package/dist/context.js +2 -2
  15. package/dist/internal/credentials.d.ts +6 -0
  16. package/dist/internal/credentials.js +10 -0
  17. package/dist/internal/devices.js +7 -10
  18. package/dist/internal/file_index.js +3 -8
  19. package/dist/internal/filesystem.js +19 -12
  20. package/dist/internal/index_fs.js +3 -4
  21. package/dist/internal/inode.d.ts +2 -0
  22. package/dist/internal/inode.js +148 -185
  23. package/dist/internal/rpc.d.ts +143 -0
  24. package/dist/internal/rpc.js +251 -0
  25. package/dist/mixins/async.js +5 -6
  26. package/dist/mixins/mutexed.js +16 -10
  27. package/dist/path.js +3 -4
  28. package/dist/polyfills.js +51 -22
  29. package/dist/readline.js +32 -30
  30. package/dist/utils.d.ts +3 -2
  31. package/dist/utils.js +11 -5
  32. package/dist/vfs/acl.d.ts +2 -0
  33. package/dist/vfs/acl.js +48 -66
  34. package/dist/vfs/async.js +4 -4
  35. package/dist/vfs/dir.d.ts +4 -3
  36. package/dist/vfs/dir.js +16 -10
  37. package/dist/vfs/file.js +22 -18
  38. package/dist/vfs/ioctl.js +39 -62
  39. package/dist/vfs/promises.d.ts +33 -25
  40. package/dist/vfs/promises.js +56 -47
  41. package/dist/vfs/shared.js +7 -7
  42. package/dist/vfs/stats.js +104 -77
  43. package/dist/vfs/streams.js +11 -8
  44. package/dist/vfs/sync.d.ts +22 -11
  45. package/dist/vfs/sync.js +24 -27
  46. package/dist/vfs/types.d.ts +3 -8
  47. package/dist/vfs/watchers.js +9 -3
  48. package/dist/vfs/xattr.js +6 -12
  49. package/package.json +2 -2
  50. package/scripts/test.js +14 -7
  51. package/tests/backend/fetch.test.ts +14 -14
  52. package/tests/backend/port.test.ts +25 -17
  53. package/tests/common/context.test.ts +14 -0
  54. package/tests/common/handle.test.ts +5 -3
  55. package/tests/fetch/run.sh +2 -1
  56. package/tests/fs/scaling.test.ts +32 -0
  57. package/tests/fs/watch.test.ts +2 -5
  58. package/tests/setup/single-buffer.ts +1 -1
  59. package/tests/tsconfig.json +3 -2
  60. package/types/uint8array.d.ts +64 -0
package/dist/vfs/xattr.js CHANGED
@@ -16,14 +16,13 @@ function checkName($, name, path, syscall) {
16
16
  throw UV('ENOTSUP', syscall, path);
17
17
  }
18
18
  export async function get(path, name, opt = {}) {
19
- var _a;
20
19
  path = normalizePath(path);
21
20
  const { fs, path: resolved } = resolveMount(path, this);
22
21
  checkName(this, name, path, 'xattr.get');
23
22
  const inode = await fs.stat(resolved).catch(rethrow('xattr.get', path));
24
23
  if (checkAccess && !hasAccess(this, inode, R_OK))
25
24
  throw UV('EACCES', 'xattr.get', path);
26
- (_a = inode.attributes) !== null && _a !== void 0 ? _a : (inode.attributes = new Attributes());
25
+ inode.attributes ??= new Attributes();
27
26
  const value = inode.attributes.get(name);
28
27
  if (!value)
29
28
  throw UV('ENODATA', 'xattr.get', path);
@@ -31,7 +30,6 @@ export async function get(path, name, opt = {}) {
31
30
  return opt.encoding == 'buffer' || !opt.encoding ? buffer : buffer.toString(opt.encoding);
32
31
  }
33
32
  export function getSync(path, name, opt = {}) {
34
- var _a;
35
33
  path = normalizePath(path);
36
34
  checkName(this, name, path, 'xattr.get');
37
35
  const { fs, path: resolved } = resolveMount(path, this);
@@ -44,7 +42,7 @@ export function getSync(path, name, opt = {}) {
44
42
  }
45
43
  if (checkAccess && !hasAccess(this, inode, R_OK))
46
44
  throw UV('EACCES', 'xattr.get', path);
47
- (_a = inode.attributes) !== null && _a !== void 0 ? _a : (inode.attributes = new Attributes());
45
+ inode.attributes ??= new Attributes();
48
46
  const value = inode.attributes.get(name);
49
47
  if (!value)
50
48
  throw UV('ENODATA', 'xattr.get', path);
@@ -60,14 +58,13 @@ export function getSync(path, name, opt = {}) {
60
58
  * @param opt Options for the operation
61
59
  */
62
60
  export async function set(path, name, value, opt = {}) {
63
- var _a;
64
61
  path = normalizePath(path);
65
62
  const { fs, path: resolved } = resolveMount(path, this);
66
63
  checkName(this, name, path, 'xattr.set');
67
64
  const inode = await fs.stat(resolved).catch(rethrow('xattr.set', path));
68
65
  if (checkAccess && !hasAccess(this, inode, W_OK))
69
66
  throw UV('EACCES', 'xattr.set', path);
70
- (_a = inode.attributes) !== null && _a !== void 0 ? _a : (inode.attributes = new Attributes());
67
+ inode.attributes ??= new Attributes();
71
68
  const attr = inode.attributes.get(name);
72
69
  if (opt.create && attr)
73
70
  throw UV('EEXIST', 'xattr.set', path);
@@ -85,7 +82,6 @@ export async function set(path, name, value, opt = {}) {
85
82
  * @param opt Options for the operation
86
83
  */
87
84
  export function setSync(path, name, value, opt = {}) {
88
- var _a;
89
85
  path = normalizePath(path);
90
86
  const { fs, path: resolved } = resolveMount(path, this);
91
87
  checkName(this, name, path, 'xattr.set');
@@ -98,7 +94,7 @@ export function setSync(path, name, value, opt = {}) {
98
94
  }
99
95
  if (checkAccess && !hasAccess(this, inode, W_OK))
100
96
  throw UV('EACCES', 'xattr.set', path);
101
- (_a = inode.attributes) !== null && _a !== void 0 ? _a : (inode.attributes = new Attributes());
97
+ inode.attributes ??= new Attributes();
102
98
  const attr = inode.attributes.get(name);
103
99
  if (opt.create && attr)
104
100
  throw UV('EEXIST', 'xattr.set', path);
@@ -119,14 +115,13 @@ export function setSync(path, name, value, opt = {}) {
119
115
  * @param name Name of the attribute to remove
120
116
  */
121
117
  export async function remove(path, name) {
122
- var _a;
123
118
  path = normalizePath(path);
124
119
  const { fs, path: resolved } = resolveMount(path, this);
125
120
  checkName(this, name, path, 'xattr.remove');
126
121
  const inode = await fs.stat(resolved).catch(rethrow('xattr.remove', path));
127
122
  if (checkAccess && !hasAccess(this, inode, W_OK))
128
123
  throw UV('EACCES', 'xattr.remove', path);
129
- (_a = inode.attributes) !== null && _a !== void 0 ? _a : (inode.attributes = new Attributes());
124
+ inode.attributes ??= new Attributes();
130
125
  const attr = inode.attributes.get(name);
131
126
  if (!attr)
132
127
  throw UV('ENODATA', 'xattr.remove', path);
@@ -140,7 +135,6 @@ export async function remove(path, name) {
140
135
  * @param name Name of the attribute to remove
141
136
  */
142
137
  export function removeSync(path, name) {
143
- var _a;
144
138
  path = normalizePath(path);
145
139
  const { fs, path: resolved } = resolveMount(path, this);
146
140
  checkName(this, name, path, 'xattr.remove');
@@ -153,7 +147,7 @@ export function removeSync(path, name) {
153
147
  }
154
148
  if (checkAccess && !hasAccess(this, inode, W_OK))
155
149
  throw UV('EACCES', 'xattr.remove', path);
156
- (_a = inode.attributes) !== null && _a !== void 0 ? _a : (inode.attributes = new Attributes());
150
+ inode.attributes ??= new Attributes();
157
151
  const attr = inode.attributes.get(name);
158
152
  if (!attr)
159
153
  throw UV('ENODATA', 'xattr.remove', path);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenfs/core",
3
- "version": "2.2.2",
3
+ "version": "2.3.0",
4
4
  "description": "A filesystem, anywhere",
5
5
  "funding": {
6
6
  "type": "individual",
@@ -71,7 +71,7 @@
71
71
  "buffer": "^6.0.3",
72
72
  "eventemitter3": "^5.0.1",
73
73
  "kerium": "^1.3.4",
74
- "memium": "^0.2.0",
74
+ "memium": "^0.2.1",
75
75
  "readable-stream": "^4.5.2",
76
76
  "utilium": "^2.3.3"
77
77
  },
package/scripts/test.js CHANGED
@@ -89,11 +89,12 @@ if (options.ci) ci = await import('./ci.js');
89
89
  options.verbose && options.force && console.debug('Forcing tests to exit (--test-force-exit)');
90
90
 
91
91
  if (options.build) {
92
- !options.quiet && console.log('Building...');
92
+ !options.quiet && process.stdout.write('Building... ');
93
93
  try {
94
94
  execSync('npm run build');
95
+ console.log('done.');
95
96
  } catch {
96
- console.warn('Build failed, continuing without it.');
97
+ console.warn('failed, continuing without it.');
97
98
  }
98
99
  }
99
100
 
@@ -141,17 +142,19 @@ async function status(name) {
141
142
  return color(`(${delta} ${unit})`, '2;37');
142
143
  };
143
144
 
145
+ const maybeName = options.verbose ? `: ${name}` : '';
146
+
144
147
  return {
145
148
  async pass() {
146
- if (!options.quiet) console.log(`${color('passed', 32)}: ${name} ${time()}`);
149
+ if (!options.quiet) console.log(`${color('passed', 32)}${maybeName} ${time()}`);
147
150
  if (options.ci) await ci.completeCheck(name, 'success');
148
151
  },
149
152
  async skip() {
150
- if (!options.quiet) console.log(`${color('skipped', 33)}: ${name} ${time()}`);
153
+ if (!options.quiet) console.log(`${color('skipped', 33)}${maybeName} ${time()}`);
151
154
  if (options.ci) await ci.completeCheck(name, 'skipped');
152
155
  },
153
156
  async fail() {
154
- console.error(`${color('failed', '1;31')}: ${name} ${time()}`);
157
+ console.error(`${color('failed', '1;31')}${maybeName} ${time()}`);
155
158
  if (options.ci) await ci.completeCheck(name, 'failure');
156
159
  process.exitCode = 1;
157
160
  if (options['exit-on-fail']) process.exit();
@@ -163,7 +166,7 @@ if (!options.preserve) rmSync(options.coverage, { force: true, recursive: true }
163
166
  mkdirSync(options.coverage, { recursive: true });
164
167
 
165
168
  if (options.common) {
166
- !options.quiet && console.log('Running common tests...');
169
+ !options.quiet && process.stdout.write('Running common tests...' + (options.verbose ? '\n' : ' '));
167
170
  const { pass, fail } = await status('Common tests');
168
171
  try {
169
172
  execSync(
@@ -187,10 +190,14 @@ for (const setupFile of positionals) {
187
190
  }
188
191
 
189
192
  process.env.SETUP = setupFile;
193
+ process.env.VERBOSE = +options.verbose;
190
194
 
191
195
  const name = options['file-names'] && !options.ci ? setupFile : parse(setupFile).name;
192
196
 
193
- !options.quiet && console.log('Running tests:', name);
197
+ if (!options.quiet) {
198
+ if (options.verbose) console.log('Running tests:', name);
199
+ else process.stdout.write(`Running tests: ${name}... `);
200
+ }
194
201
 
195
202
  const { pass, fail, skip } = await status(name);
196
203
 
@@ -1,6 +1,6 @@
1
1
  import assert from 'node:assert/strict';
2
2
  import { join } from 'node:path';
3
- import { suite, test } from 'node:test';
3
+ import { after, suite, test } from 'node:test';
4
4
  import { Worker } from 'node:worker_threads';
5
5
  import { Fetch, configureSingle, fs, mounts, type FetchFS } from '../../dist/index.js';
6
6
  import { baseUrl, defaultEntries, indexPath, whenServerReady } from '../fetch/config.js';
@@ -12,17 +12,15 @@ const server = new Worker(join(import.meta.dirname, '../fetch/server.js'));
12
12
 
13
13
  await whenServerReady();
14
14
 
15
- await suite('Fetch with `disableAsyncCache`', () => {
16
- test('Configuration', async () => {
17
- await configureSingle({
18
- backend: Fetch,
19
- disableAsyncCache: true,
20
- remoteWrite: true,
21
- baseUrl,
22
- index: baseUrl + indexPath,
23
- });
24
- });
15
+ await configureSingle({
16
+ backend: Fetch,
17
+ disableAsyncCache: true,
18
+ remoteWrite: true,
19
+ baseUrl,
20
+ index: baseUrl + indexPath,
21
+ });
25
22
 
23
+ suite('Fetch with `disableAsyncCache`', () => {
26
24
  test('Read and write file', async () => {
27
25
  await fs.promises.writeFile('/example', 'test');
28
26
 
@@ -45,9 +43,11 @@ await suite('Fetch with `disableAsyncCache`', () => {
45
43
 
46
44
  test('Uncached synchronous operations throw', async () => {
47
45
  assert.throws(() => fs.readFileSync('/x.txt', 'utf8'), { code: 'EAGAIN' });
48
- await (mounts.get('/') as FetchFS)._asyncDone;
49
46
  });
50
47
  });
51
48
 
52
- await server.terminate();
53
- server.unref();
49
+ after(async () => {
50
+ await (mounts.get('/') as FetchFS)._asyncDone;
51
+ await server.terminate();
52
+ server.unref();
53
+ });
@@ -1,9 +1,9 @@
1
1
  import assert from 'node:assert/strict';
2
- import { suite, test } from 'node:test';
2
+ import { after, suite, test } from 'node:test';
3
3
  import { MessageChannel, Worker } from 'node:worker_threads';
4
- import { Port, attachFS, waitOnline } from '../../dist/backends/port.js';
4
+ import { Port, attachFS } from '../../dist/backends/port.js';
5
5
  import type { InMemoryStore, StoreFS } from '../../dist/index.js';
6
- import { InMemory, configure, configureSingle, fs, resolveMountConfig } from '../../dist/index.js';
6
+ import { InMemory, configure, configureSingle, fs, resolveMountConfig, waitOnline } from '../../dist/index.js';
7
7
  import { setupLogs } from '../logs.js';
8
8
  setupLogs();
9
9
 
@@ -29,16 +29,18 @@ await suite('Timeout', { timeout: 1000 }, () => {
29
29
 
30
30
  await assert.rejects(configured, { code: 'EIO', message: /RPC Failed/ });
31
31
  });
32
- });
33
32
 
34
- timeoutChannel.port1.unref();
33
+ after(() => {
34
+ timeoutChannel.port1.unref();
35
+ });
36
+ });
35
37
 
36
38
  // Test configuration
37
39
 
38
40
  const configPort = new Worker(import.meta.dirname + '/config.worker.js');
39
41
  await waitOnline(configPort);
40
42
 
41
- await suite('Remote FS with resolveRemoteMount', () => {
43
+ suite('Remote FS with resolveRemoteMount', () => {
42
44
  const content = 'FS is in a port';
43
45
 
44
46
  test('Configuration', async () => {
@@ -52,10 +54,12 @@ await suite('Remote FS with resolveRemoteMount', () => {
52
54
  test('Read', async () => {
53
55
  assert.equal(await fs.promises.readFile('/test', 'utf8'), content);
54
56
  });
55
- });
56
57
 
57
- await configPort.terminate();
58
- configPort.unref();
58
+ after(async () => {
59
+ await configPort.terminate();
60
+ configPort.unref();
61
+ });
62
+ });
59
63
 
60
64
  // Test using a message channel
61
65
 
@@ -87,12 +91,14 @@ await suite('FS with MessageChannel', () => {
87
91
  test('readFileSync should throw', () => {
88
92
  assert.throws(() => fs.readFileSync('/test', 'utf8'), { code: 'ENOTSUP' });
89
93
  });
90
- });
91
94
 
92
- channel.port1.close();
93
- channel.port2.close();
94
- channel.port1.unref();
95
- channel.port2.unref();
95
+ after(() => {
96
+ channel.port1.close();
97
+ channel.port2.close();
98
+ channel.port1.unref();
99
+ channel.port2.unref();
100
+ });
101
+ });
96
102
 
97
103
  // Test using a worker
98
104
 
@@ -112,7 +118,9 @@ await suite('Remote FS', () => {
112
118
  test('Read', async () => {
113
119
  assert.equal(await fs.promises.readFile('/test', 'utf8'), content);
114
120
  });
115
- });
116
121
 
117
- await remotePort.terminate();
118
- remotePort.unref();
122
+ after(async () => {
123
+ await remotePort.terminate();
124
+ remotePort.unref();
125
+ });
126
+ });
@@ -3,6 +3,7 @@ import { suite, test } from 'node:test';
3
3
  import { canary } from 'utilium';
4
4
  import { bindContext } from '../../dist/context.js';
5
5
  import * as fs from '../../dist/vfs/index.js';
6
+ import { configure, InMemory } from '../../dist/index.js';
6
7
 
7
8
  fs.mkdirSync('/ctx');
8
9
  const { fs: ctx } = bindContext({ root: '/ctx' });
@@ -58,4 +59,17 @@ suite('Context', () => {
58
59
  await watcher.return!();
59
60
  await promise;
60
61
  });
62
+
63
+ test('Path resolution of / with context root and mount point being the same', async () => {
64
+ // @zenfs/core#226
65
+ await configure({
66
+ mounts: { '/bananas': InMemory },
67
+ });
68
+
69
+ const bananas = bindContext({ root: '/bananas' });
70
+
71
+ fs.writeFileSync('/bananas/yellow', 'true');
72
+
73
+ assert.deepEqual(bananas.fs.readdirSync('/'), ['yellow']);
74
+ });
61
75
  });
@@ -1,14 +1,14 @@
1
1
  import assert from 'node:assert/strict';
2
- import { suite, test } from 'node:test';
2
+ import { after, suite, test } from 'node:test';
3
3
  import { wait } from 'utilium';
4
4
  import { constants, type FileHandle, open } from '../../dist/vfs/promises.js';
5
5
 
6
6
  const content = 'The cake is a lie',
7
7
  appended = '\nAnother lie';
8
8
 
9
- await using handle: FileHandle = await open('./test.txt', 'ws+');
9
+ const handle: FileHandle = await open('./test.txt', 'ws+');
10
10
 
11
- await suite('FileHandle', () => {
11
+ suite('FileHandle', () => {
12
12
  test('writeFile', async () => {
13
13
  await handle.writeFile(content);
14
14
  await handle.sync();
@@ -63,3 +63,5 @@ await suite('FileHandle', () => {
63
63
  assert.deepEqual(lines, ['first line', 'second line', 'third line']);
64
64
  });
65
65
  });
66
+
67
+ after(() => handle.close());
@@ -6,7 +6,8 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
6
6
  node $SCRIPT_DIR/server.js &
7
7
  PID=$!
8
8
 
9
- echo "Waiting for server to start..."
9
+ echo -n "Waiting for server to start..."
10
+ if [ -n "$VERBOSE" ]; then echo; fi
10
11
  until nc -z localhost 26514; do
11
12
  sleep 0.25
12
13
  done
@@ -0,0 +1,32 @@
1
+ import assert from 'node:assert/strict';
2
+ import { suite, test } from 'node:test';
3
+ import { fs } from '../common.js';
4
+
5
+ const n_files = 130;
6
+ const huge_size = 0x1000000;
7
+
8
+ // Tests for having a lot of various things (number of inodes/files, individual file size, etc.).
9
+ suite('Scaling', () => {
10
+ test('Lots of inodes/files', async () => {
11
+ fs.mkdirSync('/n');
12
+
13
+ for (let i = 0; i < n_files; i++) {
14
+ fs.writeFileSync('/n/' + i, i.toString(16));
15
+ }
16
+
17
+ assert.equal(fs.readdirSync('/n').length, n_files);
18
+
19
+ const results = [];
20
+
21
+ for (let i = 0; i < n_files; i++) {
22
+ results.push(fs.promises.readFile('/n/' + i, 'utf8').then(val => assert.equal(val, i.toString(16))));
23
+ }
24
+
25
+ await Promise.all(results);
26
+ });
27
+
28
+ test('Singular file size', () => {
29
+ fs.writeFileSync('/huge', new Uint8Array(huge_size));
30
+ assert.equal(fs.statSync('/huge').size, huge_size);
31
+ });
32
+ });
@@ -9,9 +9,9 @@ await fs.promises.mkdir(testDir);
9
9
  await fs.promises.writeFile(testFile, 'Initial content');
10
10
 
11
11
  /**
12
- * @todo convert using watcher to void discards pending ES proposal
12
+ * @todo convert `using watcher = ...` to void discards pending ES proposal
13
13
  */
14
- await suite('Watch', () => {
14
+ suite('Watch', async () => {
15
15
  test('Events emitted on file change', async () => {
16
16
  const { promise, resolve } = Promise.withResolvers<[string, string]>();
17
17
 
@@ -155,6 +155,3 @@ await suite('Watch', () => {
155
155
  await promise;
156
156
  });
157
157
  });
158
-
159
- await fs.promises.rm(testFile);
160
- await fs.promises.rm(testDir, { recursive: true, force: true });
@@ -3,7 +3,7 @@ import { copySync, data } from '../setup.js';
3
3
 
4
4
  await configureSingle({
5
5
  backend: SingleBuffer,
6
- buffer: new ArrayBuffer(0x100000),
6
+ buffer: new ArrayBuffer(0x1100000),
7
7
  });
8
8
 
9
9
  copySync(data);
@@ -6,7 +6,8 @@
6
6
  "noEmit": true,
7
7
  "esModuleInterop": true,
8
8
  "allowSyntheticDefaultImports": true,
9
- "allowJs": true
9
+ "allowJs": true,
10
+ "rootDir": ".."
10
11
  },
11
- "include": ["**/*.ts", "*.ts", "**/*.js"]
12
+ "include": ["**/*.ts", "*.ts", "**/*.js", "../types/uint8array.d.ts"]
12
13
  }
@@ -0,0 +1,64 @@
1
+ /**
2
+ See:
3
+ https://developer.mozilla.org/Web/JavaScript/Reference/Global_Objects/Uint8Array/toBase64
4
+ https://github.com/microsoft/TypeScript/pull/61696
5
+ https://github.com/microsoft/TypeScript/issues/61695
6
+
7
+ @todo Remove when TypeScript 5.9 is released
8
+ */
9
+
10
+ interface Uint8ArrayConstructor {
11
+ /**
12
+ * Creates a new `Uint8Array` from a base64-encoded string.
13
+ * @param string The base64-encoded string.
14
+ * @param options If provided, specifies the alphabet and handling of the last chunk.
15
+ * @returns A new `Uint8Array` instance.
16
+ * @throws {SyntaxError} If the input string contains characters outside the specified alphabet, or if the last
17
+ * chunk is inconsistent with the `lastChunkHandling` option.
18
+ */
19
+ fromBase64: (string: string) => Uint8Array;
20
+
21
+ /**
22
+ * Creates a new `Uint8Array` from a base16-encoded string.
23
+ * @returns A new `Uint8Array` instance.
24
+ */
25
+ fromHex: (string: string) => Uint8Array;
26
+ }
27
+
28
+ interface Uint8Array<TArrayBuffer extends ArrayBufferLike> {
29
+ /**
30
+ * Converts the `Uint8Array` to a base64-encoded string.
31
+ * @param options If provided, sets the alphabet and padding behavior used.
32
+ * @returns A base64-encoded string.
33
+ */
34
+ toBase64: () => string;
35
+
36
+ /**
37
+ * Sets the `Uint8Array` from a base64-encoded string.
38
+ * @param string The base64-encoded string.
39
+ * @param options If provided, specifies the alphabet and handling of the last chunk.
40
+ * @returns An object containing the number of bytes read and written.
41
+ * @throws {SyntaxError} If the input string contains characters outside the specified alphabet, or if the last
42
+ * chunk is inconsistent with the `lastChunkHandling` option.
43
+ */
44
+ setFromBase64?: (string: string) => {
45
+ read: number;
46
+ written: number;
47
+ };
48
+
49
+ /**
50
+ * Converts the `Uint8Array` to a base16-encoded string.
51
+ * @returns A base16-encoded string.
52
+ */
53
+ toHex: () => string;
54
+
55
+ /**
56
+ * Sets the `Uint8Array` from a base16-encoded string.
57
+ * @param string The base16-encoded string.
58
+ * @returns An object containing the number of bytes read and written.
59
+ */
60
+ setFromHex?: (string: string) => {
61
+ read: number;
62
+ written: number;
63
+ };
64
+ }