@axium/storage 0.3.17 → 0.4.1

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.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import type { StorageItemMetadata, StorageItemUpdate, UserFilesInfo } from './common.js';
2
- import type { ItemSelection } from './selection.js';
3
2
  export declare function parseItem(result: StorageItemMetadata): StorageItemMetadata;
4
3
  export interface UploadOptions {
5
4
  parentId?: string;
@@ -13,8 +12,3 @@ export declare function downloadItem(fileId: string): Promise<Blob>;
13
12
  export declare function updateItemMetadata(fileId: string, metadata: StorageItemUpdate): Promise<StorageItemMetadata>;
14
13
  export declare function deleteItem(fileId: string): Promise<StorageItemMetadata>;
15
14
  export declare function getUserFiles(userId: string): Promise<UserFilesInfo>;
16
- export interface _Sidebar {
17
- selection: ItemSelection<string, StorageItemMetadata>;
18
- items: StorageItemMetadata[];
19
- getDirectory(id: string, assignTo?: StorageItemMetadata[]): Promise<StorageItemMetadata[]>;
20
- }
package/dist/plugin.d.ts CHANGED
@@ -37,8 +37,9 @@ declare const _default: {
37
37
  exports: {
38
38
  ".": string;
39
39
  "./*": string;
40
- "./lib": string;
41
- "./lib/*": string;
40
+ "./sidebar": string;
41
+ "./components": string;
42
+ "./components/*": string;
42
43
  };
43
44
  files: string[];
44
45
  scripts: {
package/dist/server.js CHANGED
@@ -62,7 +62,8 @@ export async function currentUsage(userId) {
62
62
  .select(eb => eb.fn.countAll().as('items'))
63
63
  .select(eb => eb.fn.sum('size').as('bytes'))
64
64
  .executeTakeFirstOrThrow();
65
- result.bytes ||= 0;
65
+ result.bytes = Number(result.bytes || 0);
66
+ result.items = Number(result.items);
66
67
  return result;
67
68
  }
68
69
  export async function get(itemId) {
@@ -5,9 +5,8 @@
5
5
  import { deleteItem, getDirectoryMetadata, updateItemMetadata } from '@axium/storage/client';
6
6
  import type { StorageItemMetadata } from '@axium/storage/common';
7
7
 
8
- const { id }: { id: string } = $props();
8
+ let { id, items = $bindable([]) }: { id: string; items?: StorageItemMetadata[] } = $props();
9
9
 
10
- let items = $state<StorageItemMetadata[]>([]);
11
10
  let activeIndex = $state<number>(-1);
12
11
  let activeItem = $derived(items[activeIndex]);
13
12
  const dialogs = $state<Record<string, HTMLDialogElement>>({});
@@ -36,7 +35,7 @@
36
35
  {/snippet}
37
36
 
38
37
  <div class="StorageList">
39
- {#await getDirectoryMetadata(id).then(data => (items = data)) then}
38
+ {#await items.length || getDirectoryMetadata(id).then(data => (items = data)) then}
40
39
  <div class="StorageListItem header">
41
40
  <span></span>
42
41
  <span>Name</span>
@@ -45,7 +44,7 @@
45
44
  </div>
46
45
  {#each items as item, i (item.id)}
47
46
  <div class="StorageListItem">
48
- <Icon i={iconForMime(item.type)} />
47
+ <dfn title={item.type}><Icon i={iconForMime(item.type)} /></dfn>
49
48
  <span class="name">{item.name}</span>
50
49
  <span>{item.modifiedAt.toLocaleString()}</span>
51
50
  <span>{formatBytes(item.size)}</span>
@@ -1,38 +1,26 @@
1
1
  <script lang="ts">
2
- import { getDirectoryMetadata, type _Sidebar } from '@axium/storage/client';
3
2
  import type { StorageItemMetadata } from '@axium/storage/common';
4
- import { ItemSelection } from '@axium/storage/selection';
5
- import { setContext } from 'svelte';
6
3
  import StorageSidebarItem from './StorageSidebarItem.svelte';
4
+ import { items as sb_items, getDirectory } from '@axium/storage/sidebar';
7
5
 
8
- const { root }: { root: string | StorageItemMetadata[] } = $props();
6
+ let { root }: { root: string | StorageItemMetadata[] } = $props();
9
7
 
10
8
  let items = $state<StorageItemMetadata[]>([]);
11
9
 
12
- const allItems: StorageItemMetadata[] = [];
13
-
14
- const sidebar = $state<_Sidebar>({
15
- selection: new ItemSelection(allItems),
16
- items: allItems,
17
- async getDirectory(id: string, assignTo?: StorageItemMetadata[]) {
18
- const data = await getDirectoryMetadata(id);
19
- this.items.push(...data);
20
- assignTo = data;
21
- return data;
22
- },
23
- });
24
-
25
- setContext('files:sidebar', () => sidebar);
26
-
27
- if (typeof root == 'string') allItems.push(...items);
10
+ if (typeof root != 'string') {
11
+ sb_items.push(...root);
12
+ items = root;
13
+ }
28
14
  </script>
29
15
 
30
- <div id="FilesSidebar">
31
- {#await typeof root == 'string' ? sidebar.getDirectory(root, items) : root}
16
+ <div id="StorageSidebar">
17
+ {#await typeof root == 'string' ? getDirectory(root, items) : root}
32
18
  <i>Loading...</i>
33
19
  {:then}
34
20
  {#each items as _, i (_.id)}
35
21
  <StorageSidebarItem bind:item={items[i]} bind:items />
22
+ {:else}
23
+ <i>No files yet</i>
36
24
  {/each}
37
25
  {:catch error}
38
26
  <i style:color="#c44">{error.message}</i>
@@ -1,24 +1,20 @@
1
1
  <script lang="ts">
2
2
  import * as icon from '@axium/core/icons';
3
3
  import { ClipboardCopy, FormDialog, Icon } from '@axium/server/components';
4
- import { deleteItem, updateItemMetadata, type _Sidebar } from '@axium/storage/client';
4
+ import { deleteItem, updateItemMetadata } from '@axium/storage/client';
5
5
  import type { StorageItemMetadata } from '@axium/storage/common';
6
- import { getContext } from 'svelte';
7
6
  import StorageSidebarItem from './StorageSidebarItem.svelte';
7
+ import { debug, getDirectory, selection, toggle, toggleRange } from '@axium/storage/sidebar';
8
8
 
9
9
  let {
10
10
  item = $bindable(),
11
11
  items = $bindable(),
12
- debug = false,
13
12
  }: {
14
13
  item: StorageItemMetadata;
15
14
  /** The items list for the parent directory */
16
15
  items: StorageItemMetadata[];
17
- debug?: boolean;
18
16
  } = $props();
19
17
 
20
- const sb = getContext<() => _Sidebar>('files:sidebar')();
21
-
22
18
  const dialogs = $state<Record<string, HTMLDialogElement>>({});
23
19
  let popover = $state<HTMLDivElement>();
24
20
 
@@ -29,11 +25,11 @@
29
25
  }
30
26
 
31
27
  function onclick(e: MouseEvent) {
32
- if (e.shiftKey) sb.selection.toggleRange(item.id);
33
- else if (e.ctrlKey) sb.selection.toggle(item.id);
28
+ if (e.shiftKey) toggleRange(item.id);
29
+ else if (e.ctrlKey) toggle(item.id);
34
30
  else {
35
- sb.selection.clear();
36
- sb.selection.add(item.id);
31
+ selection.clear();
32
+ selection.add(item.id);
37
33
  }
38
34
  }
39
35
 
@@ -63,12 +59,12 @@
63
59
 
64
60
  {#if item.type == 'inode/directory'}
65
61
  <details>
66
- <summary class={['StorageSidebarItem', sb.selection.has(item.id) && 'selected']} {onclick} {oncontextmenu}>
62
+ <summary class={['StorageSidebarItem', selection.has(item.id) && 'selected']} {onclick} {oncontextmenu}>
67
63
  <Icon i={icon.forMime(item.type)} />
68
64
  <span class="name">{item.name}</span>
69
65
  </summary>
70
66
  <div>
71
- {#await sb.getDirectory(item.id, children)}
67
+ {#await getDirectory(item.id, children)}
72
68
  <i>Loading...</i>
73
69
  {:then}
74
70
  {#each children as _, i (_.id)}
@@ -80,7 +76,7 @@
80
76
  </div>
81
77
  </details>
82
78
  {:else}
83
- <div class={['StorageSidebarItem', sb.selection.has(item.id) && 'selected']} {onclick} {oncontextmenu}>
79
+ <div class={['StorageSidebarItem', selection.has(item.id) && 'selected']} {onclick} {oncontextmenu}>
84
80
  <Icon i={icon.forMime(item.type)} />
85
81
  <span class="name">{item.name}</span>
86
82
  </div>
@@ -0,0 +1,42 @@
1
+ import type { StorageItemMetadata } from '@axium/storage/common';
2
+ import { getDirectoryMetadata } from '@axium/storage/client';
3
+ import { SvelteSet } from 'svelte/reactivity';
4
+
5
+ export const selection = $state(new SvelteSet());
6
+
7
+ export const items = $state<StorageItemMetadata[]>([]);
8
+
9
+ let lastSelected = $state<string>();
10
+
11
+ export function getLastedSelected() {
12
+ return lastSelected;
13
+ }
14
+
15
+ /** @todo move this into user preferences somehow */
16
+ export let debug = false;
17
+
18
+ export async function getDirectory(id: string, assignTo?: StorageItemMetadata[]) {
19
+ const data = await getDirectoryMetadata(id);
20
+ items.push(...data);
21
+ assignTo = data;
22
+ return data;
23
+ }
24
+
25
+ export function toggle(id: string): boolean {
26
+ const has = selection.has(id);
27
+ if (has) selection.delete(id);
28
+ else {
29
+ selection.add(id);
30
+ lastSelected = id;
31
+ }
32
+ return has;
33
+ }
34
+
35
+ export function toggleRange(id: string) {
36
+ const from = items.findIndex(item => item.id === lastSelected);
37
+ const until = items.findIndex(item => item.id === id);
38
+ if (from === -1 || until === -1) return;
39
+
40
+ const range = items.slice(Math.min(from, until), Math.max(from, until) + 1);
41
+ for (const item of range) toggle(item.id);
42
+ }
package/lib/tsconfig.json CHANGED
@@ -2,9 +2,12 @@
2
2
  "extends": "../tsconfig.json",
3
3
  "compilerOptions": {
4
4
  "rootDir": "..",
5
- "noEmit": true
5
+ "noEmit": true,
6
+ "module": "preserve",
7
+ "moduleResolution": "Bundler",
8
+ "allowImportingTsExtensions": true
6
9
  },
7
- "include": ["**/*.svelte"],
10
+ "include": ["**/*.svelte", "**/*.ts"],
8
11
  "exclude": [],
9
12
  "references": [{ "path": ".." }]
10
13
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axium/storage",
3
- "version": "0.3.17",
3
+ "version": "0.4.1",
4
4
  "author": "James Prevett <axium@jamespre.dev> (https://jamespre.dev)",
5
5
  "description": "User file storage for Axium",
6
6
  "funding": {
@@ -22,8 +22,9 @@
22
22
  "exports": {
23
23
  ".": "./dist/index.js",
24
24
  "./*": "./dist/*.js",
25
- "./lib": "./lib/index.js",
26
- "./lib/*": "./lib/*.js"
25
+ "./sidebar": "./lib/sidebar.svelte.js",
26
+ "./components": "./lib/index.js",
27
+ "./components/*": "./lib/*.svelte"
27
28
  },
28
29
  "files": [
29
30
  "dist",
@@ -1,17 +0,0 @@
1
- import { SvelteSet } from 'svelte/reactivity';
2
- export declare class ItemSelection<T, V extends {
3
- id: T;
4
- }> extends SvelteSet<T> {
5
- /**
6
- * The list of items that can be selected.
7
- */
8
- items: V[];
9
- constructor(
10
- /**
11
- * The list of items that can be selected.
12
- */
13
- items: V[]);
14
- last?: T;
15
- toggle(id: T): boolean;
16
- toggleRange(id: T): void;
17
- }
package/dist/selection.js DELETED
@@ -1,32 +0,0 @@
1
- import { SvelteSet } from 'svelte/reactivity';
2
- export class ItemSelection extends SvelteSet {
3
- items;
4
- constructor(
5
- /**
6
- * The list of items that can be selected.
7
- */
8
- items) {
9
- super([]);
10
- this.items = items;
11
- }
12
- last;
13
- toggle(id) {
14
- const has = this.has(id);
15
- if (has)
16
- this.delete(id);
17
- else {
18
- this.add(id);
19
- this.last = id;
20
- }
21
- return has;
22
- }
23
- toggleRange(id) {
24
- const from = this.items.findIndex(item => item.id === this.last);
25
- const until = this.items.findIndex(item => item.id === id);
26
- if (from === -1 || until === -1)
27
- return;
28
- const range = this.items.slice(Math.min(from, until), Math.max(from, until) + 1);
29
- for (const item of range)
30
- this.toggle(item.id);
31
- }
32
- }