@axium/storage 0.23.1 → 0.23.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/dist/client/cli/commands.js +3 -5
- package/dist/client/sync.js +6 -11
- package/dist/node.d.ts +2 -0
- package/dist/node.js +11 -0
- package/dist/server/raw.js +3 -3
- package/package.json +1 -1
- package/routes/files/trash/+page.svelte +7 -5
|
@@ -50,16 +50,15 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
50
50
|
var e = new Error(message);
|
|
51
51
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
52
|
});
|
|
53
|
+
import { formatBytes } from '@axium/core';
|
|
53
54
|
import { Command } from 'commander';
|
|
54
55
|
import * as io from 'ioium/node';
|
|
55
56
|
import mime from 'mime';
|
|
56
57
|
import * as fs from 'node:fs';
|
|
57
58
|
import { basename } from 'node:path';
|
|
58
|
-
import {
|
|
59
|
-
import { colorItem, formatItems } from '../../node.js';
|
|
59
|
+
import { colorItem, formatItems, streamRead } from '../../node.js';
|
|
60
60
|
import * as api from '../api.js';
|
|
61
61
|
import { getDirectory, resolveItem, resolvePathWithParent, syncCache, writeCache } from '../local.js';
|
|
62
|
-
import { formatBytes } from '@axium/core';
|
|
63
62
|
export const ls = new Command('ls')
|
|
64
63
|
.alias('list')
|
|
65
64
|
.description('List the contents of a folder')
|
|
@@ -132,10 +131,9 @@ export const upload = new Command('upload')
|
|
|
132
131
|
}
|
|
133
132
|
else if (existingTarget && !opts.force)
|
|
134
133
|
throw 'File exists at remote path, use --force to overwrite it';
|
|
135
|
-
const stream = Readable.toWeb(fs.createReadStream(local));
|
|
136
134
|
const type = mime.getType(local) || 'application/octet-stream';
|
|
137
135
|
const _ = __addDisposableResource(env_1, io.start('Uploading ' + name), false);
|
|
138
|
-
const item = await api.createItem(
|
|
136
|
+
const item = await api.createItem(streamRead(local), {
|
|
139
137
|
parentId: parent?.id,
|
|
140
138
|
name,
|
|
141
139
|
size: stats.size,
|
package/dist/client/sync.js
CHANGED
|
@@ -5,11 +5,11 @@ import mime from 'mime';
|
|
|
5
5
|
import { createHash } from 'node:crypto';
|
|
6
6
|
import * as fs from 'node:fs';
|
|
7
7
|
import { basename, dirname, join, matchesGlob, relative } from 'node:path';
|
|
8
|
-
import { Readable, Writable } from 'node:stream';
|
|
9
8
|
import { pick } from 'utilium';
|
|
10
9
|
import * as z from 'zod';
|
|
10
|
+
import { streamRead, streamWrite } from '../node.js';
|
|
11
11
|
import '../polyfills.js';
|
|
12
|
-
import {
|
|
12
|
+
import { createDirectory, createItem, deleteItem, downloadItemStream, updateItem } from './api.js';
|
|
13
13
|
/**
|
|
14
14
|
* A Sync is a storage item that has been selected for synchronization by the user.
|
|
15
15
|
* Importantly, it is *only* the "top-level" item.
|
|
@@ -141,8 +141,7 @@ export async function doSync(sync, opt) {
|
|
|
141
141
|
else {
|
|
142
142
|
const type = mime.getType(dirent._path) || 'application/octet-stream';
|
|
143
143
|
const { size } = fs.statSync(join(sync.local_path, dirent._path));
|
|
144
|
-
|
|
145
|
-
const stream = Readable.toWeb(fs.createReadStream(join(sync.local_path, dirent._path)));
|
|
144
|
+
const stream = streamRead(join(sync.local_path, dirent._path));
|
|
146
145
|
const file = await createItem(stream, { ...uploadOpts, type, size });
|
|
147
146
|
_items.set(dirent._path, Object.assign(pick(file, 'id', 'modifiedAt', 'hash'), { path: dirent._path }));
|
|
148
147
|
}
|
|
@@ -168,23 +167,19 @@ export async function doSync(sync, opt) {
|
|
|
168
167
|
fs.mkdirSync(fullPath, { recursive: true });
|
|
169
168
|
}
|
|
170
169
|
else {
|
|
171
|
-
|
|
172
|
-
const stream = await downloadItemStream(item.id);
|
|
173
|
-
await stream.pipeTo(Writable.toWeb(writeStream));
|
|
170
|
+
await streamWrite(fullPath, await downloadItemStream(item.id));
|
|
174
171
|
}
|
|
175
172
|
});
|
|
176
173
|
if (!opt.verbose && delta.modified.length)
|
|
177
174
|
io.start('Syncing modified items');
|
|
178
175
|
await applyAction(opt, delta.modified, item => (opt.verbose ? 'Updating ' : '') + item.path, async (item) => {
|
|
179
176
|
if (item.modifiedAt.getTime() > fs.statSync(join(sync.local_path, item.path)).mtime.getTime()) {
|
|
180
|
-
|
|
181
|
-
const stream = await downloadItemStream(item.id);
|
|
182
|
-
await stream.pipeTo(Writable.toWeb(writeStream));
|
|
177
|
+
await streamWrite(join(sync.local_path, item.path), await downloadItemStream(item.id));
|
|
183
178
|
return 'server.';
|
|
184
179
|
}
|
|
185
180
|
else {
|
|
186
181
|
const { size } = fs.statSync(join(sync.local_path, item.path));
|
|
187
|
-
const stream =
|
|
182
|
+
const stream = streamRead(join(sync.local_path, item.path));
|
|
188
183
|
const updated = await updateItem(item.id, size, stream);
|
|
189
184
|
_items.set(item.path, Object.assign(pick(updated, 'id', 'modifiedAt', 'hash'), { path: item.path }));
|
|
190
185
|
return 'local.';
|
package/dist/node.d.ts
CHANGED
|
@@ -10,4 +10,6 @@ interface FormatItemsConfig {
|
|
|
10
10
|
humanReadable: boolean;
|
|
11
11
|
}
|
|
12
12
|
export declare function formatItems({ items, users, humanReadable }: FormatItemsConfig): Generator<string>;
|
|
13
|
+
export declare function streamRead(path: string, start?: number, end?: number): ReadableStream<Uint8Array<ArrayBuffer>>;
|
|
14
|
+
export declare function streamWrite(path: string, stream: ReadableStream): Promise<void>;
|
|
13
15
|
export {};
|
package/dist/node.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { formatBytes } from '@axium/core/format';
|
|
2
2
|
import { styleText } from 'node:util';
|
|
3
|
+
import { Readable, Writable } from 'node:stream';
|
|
4
|
+
import { createReadStream, createWriteStream } from 'node:fs';
|
|
3
5
|
const executables = ['application/x-pie-executable', 'application/x-sharedlib', 'application/vnd.microsoft.portable-executable'];
|
|
4
6
|
const archives = [
|
|
5
7
|
'application/gzip',
|
|
@@ -48,3 +50,12 @@ export function* formatItems({ items, users, humanReadable }) {
|
|
|
48
50
|
yield `${type}${ownerPerm}${ownerPerm}. ${owner.padEnd(nameWidth)} ${item.__size.padStart(sizeWidth)} ${formatDate(item.modifiedAt)} ${colorItem(item)}`;
|
|
49
51
|
}
|
|
50
52
|
}
|
|
53
|
+
// 2 MiB
|
|
54
|
+
const highWaterMark = 1024 * 1024 * 2;
|
|
55
|
+
export function streamRead(path, start, end) {
|
|
56
|
+
// cast because Node.js' internals use different types from lib.dom.d.ts
|
|
57
|
+
return Readable.toWeb(createReadStream(path, { start, end, highWaterMark }));
|
|
58
|
+
}
|
|
59
|
+
export async function streamWrite(path, stream) {
|
|
60
|
+
await stream.pipeTo(Writable.toWeb(createWriteStream(path, { highWaterMark })));
|
|
61
|
+
}
|
package/dist/server/raw.js
CHANGED
|
@@ -4,10 +4,10 @@ import { authRequestForItem, requireSession } from '@axium/server/auth';
|
|
|
4
4
|
import { error, withError } from '@axium/server/requests';
|
|
5
5
|
import { addRoute } from '@axium/server/routes';
|
|
6
6
|
import { createHash } from 'node:crypto';
|
|
7
|
-
import { copyFileSync,
|
|
7
|
+
import { copyFileSync, renameSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
8
8
|
import { join } from 'node:path/posix';
|
|
9
|
-
import { Readable } from 'node:stream';
|
|
10
9
|
import * as z from 'zod';
|
|
10
|
+
import { streamRead } from '../node.js';
|
|
11
11
|
import '../polyfills.js';
|
|
12
12
|
import { getLimits } from './config.js';
|
|
13
13
|
import { getUserStats } from './db.js';
|
|
@@ -139,7 +139,7 @@ addRoute({
|
|
|
139
139
|
headers: { 'Content-Range': `bytes */${item.size}` },
|
|
140
140
|
});
|
|
141
141
|
}
|
|
142
|
-
const content =
|
|
142
|
+
const content = streamRead(path, start, end);
|
|
143
143
|
return new Response(content, {
|
|
144
144
|
status: BigInt(length) == item.size ? 200 : 206,
|
|
145
145
|
headers: {
|
package/package.json
CHANGED
|
@@ -27,11 +27,13 @@
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
function useAndClearActive(thunk: () => any) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
return () => {
|
|
31
|
+
if (!activeItem) throw text('storage.generic.no_item');
|
|
32
|
+
const result = thunk();
|
|
33
|
+
const index = items.findIndex(item => item.id === activeId);
|
|
34
|
+
if (index !== -1) items.splice(index, 1);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
35
37
|
}
|
|
36
38
|
</script>
|
|
37
39
|
|