src
pages
configurator
constituent
engine
input
native-fs
opensubsonic
s3
orchestrator
input-cache
queue-audio
queue-tracks
output
processor
scripts
configurator
processor
theme
···
45
45
// CONNECTIONS
46
46
////////////////////////////////////////////// Applet connections
47
47
const CONNECTIONS = {
48
48
-
"file+local": "../../input/native-fs",
49
49
-
opensubsonic: "../../input/opensubsonic",
50
50
-
s3: "../../input/s3",
48
48
+
"file+local": "/input/native-fs",
49
49
+
opensubsonic: "/input/opensubsonic",
50
50
+
s3: "/input/s3",
51
51
};
52
52
53
53
type Scheme = keyof typeof CONNECTIONS;
···
100
100
border-radius: 4px;
101
101
}
102
102
103
103
-
progress[value]::-webkit-progress-value,
103
103
+
progress[value]::-webkit-progress-value {
104
104
+
border-radius: 4px;
105
105
+
background-color: color-mix(in oklch, currentColor 90%, transparent);
106
106
+
}
107
107
+
104
108
progress[value]::-moz-progress-bar {
105
109
border-radius: 4px;
106
110
background-color: color-mix(in oklch, currentColor 50%, transparent);
···
334
338
335
339
// Applet connections
336
340
const configurator = {
337
337
-
input: await applet("../../../configurator/input"),
338
338
-
output: await applet<ManagedOutput>("../../../configurator/output"),
341
341
+
input: await applet("/configurator/input"),
342
342
+
output: await applet<ManagedOutput>("/configurator/output"),
339
343
};
340
344
341
345
const engine = {
342
342
-
audio: await applet<AudioEngine.State>("../../engine/audio", { groupId: groupId() }),
343
343
-
queue: await applet<QueueEngine.State>("../../engine/queue", { groupId: groupId() }),
346
346
+
audio: await applet<AudioEngine.State>("/engine/audio", { groupId: groupId() }),
347
347
+
queue: await applet<QueueEngine.State>("/engine/queue", { groupId: groupId() }),
344
348
};
345
349
346
350
const _orchestrator = {
347
347
-
queueAudio: await applet("../../../orchestrator/queue-audio", {
351
351
+
queueAudio: await applet("/orchestrator/queue-audio", {
348
352
groupId: groupId(),
349
353
}),
350
354
351
355
// When using the `main` group, load additional orchestrators:
352
356
inputCache:
353
357
context.groupId === undefined || context.groupId === "main"
354
354
-
? await applet("../../../orchestrator/input-cache")
358
358
+
? await applet("/orchestrator/input-cache")
355
359
: undefined,
356
360
queueTracks:
357
361
context.groupId === undefined || context.groupId === "main"
358
358
-
? applet("../../../orchestrator/queue-tracks")
362
362
+
? applet("/orchestrator/queue-tracks")
359
363
: undefined,
360
364
};
361
365
362
366
const processor = {
363
363
-
artwork: await applet("../../../processor/artwork"),
367
367
+
artwork: await applet("/processor/artwork"),
364
368
};
365
369
366
370
////////////////////////////////////////////
···
4
4
import type { State } from "./types.d.ts";
5
5
6
6
import { register } from "@scripts/applet/common";
7
7
-
import { endpoint } from "@scripts/common";
7
7
+
import { endpoint, SharedWorker } from "@scripts/common";
8
8
9
9
////////////////////////////////////////////
10
10
// SETUP
11
11
////////////////////////////////////////////
12
12
const worker = endpoint<Actions>(
13
13
-
new Worker("../../../scripts/engine/queue/worker", { type: "module" }),
13
13
+
new SharedWorker("../../../scripts/engine/queue/worker", { type: "module" }).port,
14
14
);
15
15
16
16
// Register applet
···
26
26
27
27
// Constituents
28
28
const constituents = [
29
29
-
{ url: "constituent/blur/artwork-controller", title: "(WIP) Blur ⦚ Artwork Controller" },
29
29
+
{ url: "constituent/blur/artwork-controller/", title: "(WIP) Blur ⦚ Artwork Controller" },
30
30
];
31
31
32
32
// Applets
···
19
19
import type { Actions } from "@scripts/input/native-fs/worker";
20
20
import type { Track } from "@applets/core/types.d.ts";
21
21
import { register } from "@scripts/applet/common";
22
22
-
import { endpoint, inIframe } from "@scripts/common";
22
22
+
import { endpoint, inIframe, SharedWorker } from "@scripts/common";
23
23
import * as Mounting from "@scripts/input/native-fs/mounting";
24
24
25
25
////////////////////////////////////////////
26
26
// SETUP
27
27
////////////////////////////////////////////
28
28
const worker = endpoint<Actions>(
29
29
-
new Worker("../../../scripts/input/native-fs/worker", { type: "module" }),
29
29
+
new SharedWorker("../../../scripts/input/native-fs/worker", { type: "module" }).port,
30
30
);
31
31
32
32
// Register applet
···
21
21
import type { Actions } from "@scripts/input/opensubsonic/worker";
22
22
import type { Track } from "@applets/core/types.d.ts";
23
23
import { register } from "@scripts/applet/common";
24
24
-
import { endpoint, inIframe } from "@scripts/common";
24
24
+
import { endpoint, inIframe, SharedWorker } from "@scripts/common";
25
25
26
26
////////////////////////////////////////////
27
27
// SETUP
28
28
////////////////////////////////////////////
29
29
const worker = endpoint<Actions>(
30
30
-
new Worker("../../../scripts/input/opensubsonic/worker", { type: "module" }),
30
30
+
new SharedWorker("../../../scripts/input/opensubsonic/worker", { type: "module" }).port,
31
31
);
32
32
33
33
// Register applet
···
41
41
42
42
import type { Track } from "@applets/core/types.d.ts";
43
43
import { register } from "@scripts/applet/common";
44
44
-
import { endpoint, inIframe } from "@scripts/common";
44
44
+
import { endpoint, inIframe, SharedWorker } from "@scripts/common";
45
45
46
46
////////////////////////////////////////////
47
47
// SETUP
48
48
////////////////////////////////////////////
49
49
const worker = endpoint<Actions>(
50
50
-
new Worker("../../../scripts/input/s3/worker", { type: "module" }),
50
50
+
new SharedWorker("../../../scripts/input/s3/worker", { type: "module" }).port,
51
51
);
52
52
53
53
// Register applet
···
14
14
15
15
// Applet connections
16
16
const configurator = {
17
17
-
input: applet("../../configurator/input"),
18
18
-
output: applet<ManagedOutput>("../../configurator/output"),
17
17
+
input: applet("/configurator/input"),
18
18
+
output: applet<ManagedOutput>("/configurator/output"),
19
19
};
20
20
21
21
const processor = {
22
22
-
metadata: applet("../../processor/metadata"),
22
22
+
metadata: applet("/processor/metadata"),
23
23
};
24
24
25
25
// Start processing once settled and tracks are loaded
···
14
14
15
15
// Applet connections
16
16
const configurator = {
17
17
-
input: await applet("../../configurator/input"),
18
18
-
output: await applet<ManagedOutput>("../../configurator/output"),
17
17
+
input: await applet("/configurator/input"),
18
18
+
output: await applet<ManagedOutput>("/configurator/output"),
19
19
};
20
20
21
21
const engine = {
22
22
-
audio: await applet<AudioEngine.State>("../../engine/audio", { groupId: context.groupId }),
23
23
-
queue: await applet<QueueEngine.State>("../../engine/queue", { groupId: context.groupId }),
22
22
+
audio: await applet<AudioEngine.State>("/engine/audio", { groupId: context.groupId }),
23
23
+
queue: await applet<QueueEngine.State>("/engine/queue", { groupId: context.groupId }),
24
24
};
25
25
26
26
////////////////////////////////////////////
···
13
13
14
14
// Applet connections
15
15
const configurator = {
16
16
-
output: await applet<ManagedOutput>("../../configurator/output"),
16
16
+
output: await applet<ManagedOutput>("/configurator/output"),
17
17
};
18
18
19
19
const engine = {
20
20
-
queue: await applet<QueueEngine.State>("../../engine/queue", { groupId: context.groupId }),
20
20
+
queue: await applet<QueueEngine.State>("/engine/queue", { groupId: context.groupId }),
21
21
};
22
22
23
23
////////////////////////////////////////////
···
2
2
import type { Actions } from "@scripts/output/indexed-db/worker";
3
3
import type { ManagedOutput, Track } from "@applets/core/types.d.ts";
4
4
import { register } from "@scripts/applet/common";
5
5
-
import { endpoint } from "@scripts/common";
5
5
+
import { SharedWorker, endpoint } from "@scripts/common";
6
6
import { INITIAL_MANAGED_OUTPUT, outputManager } from "@scripts/output/common";
7
7
8
8
////////////////////////////////////////////
9
9
// SETUP
10
10
////////////////////////////////////////////
11
11
const worker = endpoint<Actions>(
12
12
-
new Worker("../../../scripts/output/indexed-db/worker", { type: "module" }),
12
12
+
new SharedWorker("../../../scripts/output/indexed-db/worker", { type: "module" }).port,
13
13
);
14
14
15
15
// Register applet
···
6
6
import type { ManagedOutput, Track } from "@applets/core/types";
7
7
import { register } from "@scripts/applet/common";
8
8
import { INITIAL_MANAGED_OUTPUT, outputManager } from "@scripts/output/common";
9
9
-
import { endpoint, jsonDecode, jsonEncode } from "@scripts/common";
9
9
+
import { endpoint, SharedWorker } from "@scripts/common";
10
10
import { IDB_DEVICE_KEY } from "@scripts/output/native-fs/constants";
11
11
12
12
////////////////////////////////////////////
13
13
// SETUP
14
14
////////////////////////////////////////////
15
15
const worker = endpoint<Actions>(
16
16
-
new Worker("../../../scripts/output/native-fs/worker", { type: "module" }),
16
16
+
new SharedWorker("../../../scripts/output/native-fs/worker", { type: "module" }).port,
17
17
);
18
18
19
19
// Register applet
···
2
2
import type { Actions } from "@scripts/processor/artwork/worker";
3
3
import type { ArtworkRequest } from "./types.d.ts";
4
4
import { register } from "@scripts/applet/common";
5
5
-
import { endpoint } from "@scripts/common";
5
5
+
import { endpoint, SharedWorker } from "@scripts/common";
6
6
7
7
////////////////////////////////////////////
8
8
// SETUP
9
9
////////////////////////////////////////////
10
10
const worker = endpoint<Actions>(
11
11
-
new Worker("../../../scripts/processor/artwork/worker", { type: "module" }),
11
11
+
new SharedWorker("../../../scripts/processor/artwork/worker", { type: "module" }).port,
12
12
);
13
13
14
14
// Register
···
1
1
<script>
2
2
import type { Actions } from "@scripts/processor/metadata/worker";
3
3
import { register } from "@scripts/applet/common";
4
4
-
import { endpoint } from "@scripts/common";
4
4
+
import { endpoint, SharedWorker } from "@scripts/common";
5
5
6
6
////////////////////////////////////////////
7
7
// SETUP
8
8
////////////////////////////////////////////
9
9
const worker = endpoint<Actions>(
10
10
-
new Worker("../../../scripts/processor/metadata/worker", { type: "module" }),
10
10
+
new SharedWorker("../../../scripts/processor/metadata/worker", { type: "module" }).port,
11
11
);
12
12
13
13
// Register applet
···
4
4
5
5
import type { Track } from "@applets/core/types";
6
6
7
7
+
export { SharedWorkerPolyfill as SharedWorker } from "@okikio/sharedworker";
8
8
+
7
9
export function arrayShuffle<T>(array: Array<T>): Array<T> {
8
10
if (array.length === 0) {
9
11
return [];
···
43
45
return xxh32(JSON.stringify(value));
44
46
}
45
47
46
46
-
export const endpoint = createEndpoint;
48
48
+
export function endpoint<T extends Record<string, any>>(port: MessagePort) {
49
49
+
const e = createEndpoint<T>(port);
50
50
+
if ("start" in port) port.start();
51
51
+
return e;
52
52
+
}
47
53
48
54
export function expose<T extends Record<string, any>>(actions: T): T {
49
49
-
createEndpoint<T>(self as MessageEndpoint).expose(actions);
55
55
+
(self as unknown as SharedWorkerGlobalScope).onconnect = (event: MessageEvent) => {
56
56
+
const port = event.ports[0];
57
57
+
createEndpoint<T>(port).expose(actions);
58
58
+
if ("start" in port) port.start();
59
59
+
};
60
60
+
50
61
return actions;
51
62
}
52
63
···
1
1
export const METHODS = ["browser", "custom", "device"] as const;
2
2
3
3
export const CONNECTIONS = {
4
4
-
browser: "../../output/indexed-db/",
4
4
+
browser: "/output/indexed-db/",
5
5
custom: undefined,
6
6
-
device: "../../output/native-fs/",
6
6
+
device: "/output/native-fs/",
7
7
};
8
8
9
9
export const DEFAULT_METHOD: (typeof METHODS)[number] = "browser";
···
1
1
import type { IPicture } from "music-metadata";
2
2
-
import { SharedWorkerPolyfill as SharedWorker } from "@okikio/sharedworker";
3
2
import * as IDB from "idb-keyval";
4
3
5
4
import type { Actions as MetadataActions } from "../metadata/worker";
6
5
import type { Artwork, ArtworkRequest } from "./types";
7
7
-
import { endpoint, expose } from "@scripts/common";
6
6
+
import { SharedWorker, endpoint, expose } from "@scripts/common";
8
7
import { IDB_ARTWORK_PREFIX } from "./constants";
9
8
10
9
// State
···
12
11
13
12
// Metadata worker
14
13
const metadataWorker = endpoint<MetadataActions>(
15
15
-
new SharedWorker("../metadata/worker", {
16
16
-
type: "module",
17
17
-
}).port,
14
14
+
new SharedWorker("../metadata/worker", { type: "module" }).port,
18
15
);
19
16
20
17
////////////////////////////////////////////
···
18
18
const labelB = "Deck B";
19
19
20
20
const configurator = {
21
21
-
output: await applet<ManagedOutput>("../../configurator/output"),
21
21
+
output: await applet<ManagedOutput>("/configurator/output"),
22
22
};
23
23
24
24
const _constituent = {
25
25
-
a: applet("../../constituent/blur/artwork-controller", { container, groupId: labelA }),
26
26
-
b: applet("../../constituent/blur/artwork-controller", { container, groupId: labelB }),
25
25
+
a: applet("/constituent/blur/artwork-controller", { container, groupId: labelA }),
26
26
+
b: applet("/constituent/blur/artwork-controller", { container, groupId: labelB }),
27
27
};
28
28
29
29
const _orchestrator = {
30
30
-
queueTracks: applet("../../orchestrator/queue-tracks", { groupId: labelA }),
30
30
+
queueTracks: applet("/orchestrator/queue-tracks", { groupId: labelA }),
31
31
};
32
32
33
33
// const engine = {
34
34
// queue: {
35
35
-
// a: await applet<QueueEngine.State>("../../engine/queue", { groupId: labelA }),
36
36
-
// b: await applet<QueueEngine.State>("../../engine/queue", { groupId: labelB }),
35
35
+
// a: await applet<QueueEngine.State>("/engine/queue", { groupId: labelA }),
36
36
+
// b: await applet<QueueEngine.State>("/engine/queue", { groupId: labelB }),
37
37
// },
38
38
// };
39
39
···
14
14
import type * as AudioUI from "@applets/constituent/pilot/audio/types";
15
15
16
16
const engine = {
17
17
-
audio: await applet<AudioEngine.State>("../../engine/audio"),
18
18
-
queue: await applet<QueueEngine.State>("../../engine/queue"),
17
17
+
audio: await applet<AudioEngine.State>("/engine/audio"),
18
18
+
queue: await applet<QueueEngine.State>("/engine/queue"),
19
19
};
20
20
21
21
const _orchestrator = {
22
22
-
input: await applet("../../orchestrator/input-cache"),
23
23
-
queueAudio: await applet("../../orchestrator/queue-audio"),
24
24
-
queueTracks: await applet("../../orchestrator/queue-tracks"),
22
22
+
input: await applet("/orchestrator/input-cache"),
23
23
+
queueAudio: await applet("/orchestrator/queue-audio"),
24
24
+
queueTracks: await applet("/orchestrator/queue-tracks"),
25
25
};
26
26
27
27
const ui = {
28
28
-
audio: await applet<AudioUI.State>("../../constituent/pilot/audio/", { setHeight: true }),
28
28
+
audio: await applet<AudioUI.State>("/constituent/pilot/audio/", { setHeight: true }),
29
29
};
30
30
31
31
////////////////////////////////////////////
···
13
13
// 🗂️ Applets
14
14
////////////////////////////////////////////
15
15
const configurator = {
16
16
-
input: await applet("../../configurator/input"),
17
17
-
output: await applet<ManagedOutput>("../../configurator/output"),
16
16
+
input: await applet("/configurator/input"),
17
17
+
output: await applet<ManagedOutput>("/configurator/output"),
18
18
};
19
19
20
20
const orchestrator = {
21
21
-
input: await applet("../../orchestrator/input-cache"),
21
21
+
input: await applet("/orchestrator/input-cache"),
22
22
};
23
23
24
24
////////////////////////////////////////////