@axium/client 0.24.2 → 0.25.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.
@@ -3,7 +3,7 @@ import { $API } from '@axium/core/api';
3
3
  import type { RequestMethod } from '@axium/core/requests';
4
4
  export declare let token: string | null;
5
5
  export declare function setToken(value: string | null): void;
6
- export declare let prefix: string;
6
+ export declare let prefix: string, origin: string;
7
7
  export declare function setPrefix(value: string): void;
8
8
  /**
9
9
  * Only for use on non-browser clients, e.g. Node.js
package/dist/requests.js CHANGED
@@ -9,9 +9,10 @@ export let token = null;
9
9
  export function setToken(value) {
10
10
  token = value;
11
11
  }
12
- export let prefix = '/api/';
12
+ export let prefix = '/api/', origin = globalThis.location?.origin || 'https://localhost/';
13
13
  export function setPrefix(value) {
14
14
  prefix = value;
15
+ origin = new URL(prefix, origin).origin;
15
16
  }
16
17
  let userAgent = null;
17
18
  /**
package/dist/user.js CHANGED
@@ -3,7 +3,7 @@ import * as z from 'zod';
3
3
  import { fetchAPI } from './requests.js';
4
4
  import { useCache } from './cache.js';
5
5
  export async function login(userId) {
6
- const options = await fetchAPI('OPTIONS', 'users/:id/auth', { type: 'login' }, userId);
6
+ const options = await fetchAPI('PUT', 'users/:id/auth', { type: 'login' }, userId);
7
7
  const response = await startAuthentication({ optionsJSON: options });
8
8
  return await fetchAPI('POST', 'users/:id/auth', response, userId);
9
9
  }
@@ -11,7 +11,7 @@ export async function login(userId) {
11
11
  * Create an elevated session for the user to perform sensitive actions.
12
12
  */
13
13
  export async function elevate(userId) {
14
- const options = await fetchAPI('OPTIONS', 'users/:id/auth', { type: 'action' }, userId);
14
+ const options = await fetchAPI('PUT', 'users/:id/auth', { type: 'action' }, userId);
15
15
  const response = await startAuthentication({ optionsJSON: options });
16
16
  await fetchAPI('POST', 'users/:id/auth', response, userId);
17
17
  }
@@ -43,7 +43,7 @@ export async function logoutCurrentSession() {
43
43
  }
44
44
  export async function register(_data) {
45
45
  const data = z.object({ name: z.string(), email: z.email() }).parse(_data);
46
- const { options, userId } = await fetchAPI('OPTIONS', 'register', data);
46
+ const { options, userId } = await fetchAPI('PUT', 'register', data);
47
47
  const response = await startRegistration({ optionsJSON: options });
48
48
  await fetchAPI('POST', 'register', {
49
49
  userId,
@@ -78,7 +78,7 @@ export async function fullUserInfo(userId) {
78
78
  */
79
79
  export async function deleteUser(userId, deletingId = userId) {
80
80
  _checkId(userId);
81
- const options = await fetchAPI('OPTIONS', 'users/:id/auth', { type: 'action' }, deletingId);
81
+ const options = await fetchAPI('PUT', 'users/:id/auth', { type: 'action' }, deletingId);
82
82
  const response = await startAuthentication({ optionsJSON: options });
83
83
  await fetchAPI('POST', 'users/:id/auth', response, deletingId);
84
84
  return await fetchAPI('DELETE', 'users/:id', response, userId);
package/lib/Audio.svelte CHANGED
@@ -3,7 +3,7 @@
3
3
  import type { Snippet } from 'svelte';
4
4
  import Icon from './Icon.svelte';
5
5
  import MediaControls from './MediaControls.svelte';
6
- import { getMetadata, MediaState, type MediaProps } from './media.svelte.js';
6
+ import { getMetadata, MediaState, type MediaPicture, type MediaProps } from './media.svelte.js';
7
7
 
8
8
  interface Props extends MediaProps {
9
9
  cover?: boolean;
@@ -15,15 +15,23 @@
15
15
 
16
16
  const id = $props.id();
17
17
 
18
- const { metadata, picture, pictureURL } = await getMetadata(rest);
18
+ let picture = $state<MediaPicture>(),
19
+ pictureURL = $state<string>(),
20
+ audioInfo = $state<[string, (string | number | null)?][]>([]);
19
21
 
20
- const audioInfo = [
21
- ['music', metadata.common.title],
22
- ['album', metadata.common.album],
23
- ['user-music', metadata.common.artist],
24
- ['hashtag', metadata.common.track.no],
25
- ['compact-disc', metadata.common.disk.no],
26
- ] as const;
22
+ getMetadata(rest).then(result => {
23
+ if (!result) return;
24
+ picture = result.picture;
25
+ pictureURL = result.pictureURL;
26
+ const { common } = result.metadata;
27
+ audioInfo = [
28
+ ['music', common.title],
29
+ ['album', common.album],
30
+ ['user-music', common.artist],
31
+ ['hashtag', common.track.no],
32
+ ['compact-disc', common.disk.no],
33
+ ] as const;
34
+ });
27
35
 
28
36
  const media = new MediaState();
29
37
  </script>
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { UserPublic } from '@axium/core';
3
3
  import { colorHashRGB } from '@axium/core/color';
4
+ import { origin } from '@axium/client';
4
5
 
5
6
  let { user, isDefault = $bindable() }: { user: UserPublic; isDefault?: boolean } = $props();
6
7
 
@@ -10,11 +11,11 @@
10
11
  </svg>`.replaceAll(/[\t\n]/g, '')
11
12
  );
12
13
 
13
- let src = $state(`/raw/pfp/${user.id}`);
14
+ let src = $state(`${origin}/raw/pfp/${user.id}`);
14
15
 
15
16
  $effect(() => {
16
17
  // Reset the attempted source when the user changes
17
- src = `/raw/pfp/${user.id}`;
18
+ src = `${origin}/raw/pfp/${user.id}`;
18
19
  });
19
20
  </script>
20
21
 
package/lib/Video.svelte CHANGED
@@ -2,7 +2,7 @@
2
2
  import type { Snippet } from 'svelte';
3
3
  import Icon from './Icon.svelte';
4
4
  import MediaControls from './MediaControls.svelte';
5
- import { getMetadata, MediaState, type MediaProps } from './media.svelte.js';
5
+ import { MediaState, type MediaProps } from './media.svelte.js';
6
6
 
7
7
  interface Props extends MediaProps {
8
8
  extraControls?: Snippet;
@@ -11,8 +11,6 @@
11
11
  const { extraControls, ...rest }: Props = $props();
12
12
  const { src } = rest;
13
13
 
14
- const { metadata, pictureURL } = await getMetadata(rest);
15
-
16
14
  const media = new MediaState();
17
15
  </script>
18
16
 
@@ -29,7 +27,6 @@
29
27
  bind:playbackRate={media.playbackRate}
30
28
  bind:ended={media.ended}
31
29
  onclick={media.click}
32
- poster={pictureURL}
33
30
  >
34
31
  <track kind="captions" />
35
32
  </video>
@@ -2,31 +2,37 @@ import { parseBuffer, parseWebStream, selectCover } from 'music-metadata';
2
2
  import type { IAudioMetadata, IPicture } from 'music-metadata';
3
3
  import type { SvelteMediaTimeRange } from 'svelte/elements';
4
4
 
5
+ type MetadataSource = ReadableStream<Uint8Array> | Uint8Array;
6
+
5
7
  export interface MediaProps {
6
8
  src: string;
7
- metadataSource?: ReadableStream<Uint8Array> | Uint8Array;
9
+ metadataSource?: MetadataSource | Promise<MetadataSource>;
8
10
  size: number | bigint;
9
11
  type: string;
10
12
  name?: string;
11
13
  }
12
14
 
15
+ export type MediaPicture = (IPicture & { data: Uint8Array<ArrayBuffer> }) | null;
16
+
13
17
  export interface MediaMetadataResult {
14
18
  metadata: IAudioMetadata;
15
- picture: (IPicture & { data: Uint8Array<ArrayBuffer> }) | null;
19
+ picture: MediaPicture;
16
20
  pictureURL?: string;
17
21
  }
18
22
 
19
- export async function getMetadata(props: MediaProps): Promise<MediaMetadataResult> {
23
+ export async function getMetadata(props: MediaProps): Promise<MediaMetadataResult | null> {
24
+ const source = await props.metadataSource;
25
+
26
+ if (!source) return null;
27
+
20
28
  const metadataFileInfo = { size: Number(props.size), mimeType: props.type, url: props.src, path: props.name };
21
29
 
22
- const metadata = await (ArrayBuffer.isView(props.metadataSource)
23
- ? parseBuffer(props.metadataSource, metadataFileInfo)
24
- : parseWebStream(props.metadataSource, metadataFileInfo));
30
+ const metadata = await (ArrayBuffer.isView(source) ? parseBuffer(source, metadataFileInfo) : parseWebStream(source, metadataFileInfo));
25
31
 
26
32
  // `picture.data`'s `source` is actually an `ArrayBufferLike`, we need it to be the more specific `ArrayBuffer`
27
33
  const picture = selectCover(metadata.common.picture) satisfies IPicture | null as MediaMetadataResult['picture'];
28
34
 
29
- if (props.metadataSource && !ArrayBuffer.isView(props.metadataSource)) await props.metadataSource.cancel();
35
+ if (source && !ArrayBuffer.isView(source)) await source.cancel();
30
36
 
31
37
  return {
32
38
  metadata,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axium/client",
3
- "version": "0.24.2",
3
+ "version": "0.25.0",
4
4
  "author": "James Prevett <jp@jamespre.dev>",
5
5
  "funding": {
6
6
  "type": "individual",
@@ -45,7 +45,7 @@
45
45
  "build": "tsc"
46
46
  },
47
47
  "peerDependencies": {
48
- "@axium/core": ">=0.28.3",
48
+ "@axium/core": ">=0.29.0",
49
49
  "ioium": "^1.0.2",
50
50
  "semver": "^7.7.4",
51
51
  "svelte": "^5.36.0",