src
pages
engine
orchestrator
processor
scripts
···
1
1
<script>
2
2
-
import type { Actions } from "@scripts/engine/queue/worker";
2
2
+
import type { Tasks } from "@scripts/engine/queue/worker";
3
3
import type { Track } from "@applets/core/types";
4
4
import type { State } from "./types.d.ts";
5
5
···
10
10
////////////////////////////////////////////
11
11
// SETUP
12
12
////////////////////////////////////////////
13
13
-
const worker = endpoint<Actions>(
13
13
+
const worker = endpoint<Tasks>(
14
14
new SharedWorker(new URL("../../../scripts/engine/queue/worker", import.meta.url), {
15
15
type: "module",
16
16
name: manifest.name,
···
18
18
);
19
19
20
20
// Register applet
21
21
-
const context = register<State>();
21
21
+
const context = register<State>({ worker });
22
22
23
23
// Initial state
24
24
context.data = {
···
36
36
context.setActionHandler("unshift", unshift);
37
37
38
38
async function add(items: Track[]) {
39
39
-
context.data = await worker.add(transfer(context.data), transfer(items));
39
39
+
context.data = await worker.add(transfer(items));
40
40
+
console.log(context.data);
40
41
}
41
42
42
43
async function pool(items: Track[]) {
43
43
-
context.data = await worker.pool(transfer(context.data), transfer(items));
44
44
+
context.data = await worker.pool(transfer(items));
44
45
}
45
46
46
47
async function shift() {
47
47
-
context.data = await worker.shift(transfer(context.data));
48
48
+
context.data = await worker.shift();
49
49
+
console.log(context.data);
48
50
}
49
51
50
52
async function unshift() {
51
51
-
context.data = await worker.unshift(transfer(context.data));
53
53
+
context.data = await worker.unshift();
52
54
}
53
55
</script>
···
88
88
{ urls: { get: resGet.url, head: resHead?.url || resGet.url } },
89
89
{
90
90
timeoutDuration: 60000 * 15,
91
91
+
worker: true,
91
92
},
92
93
);
93
94
···
47
47
}, []);
48
48
49
49
// Clear
50
50
-
engine.queue.sendAction("pool", tracks);
50
50
+
engine.queue.sendAction("pool", tracks, {
51
51
+
timeoutDuration: 60000,
52
52
+
});
51
53
},
52
54
);
53
55
});
···
1
1
<script>
2
2
-
import type { Actions } from "@scripts/processor/metadata/worker";
2
2
+
import type { Tasks } from "@scripts/processor/metadata/worker";
3
3
+
import type { Extraction, Urls } from "./types";
3
4
import { register } from "@scripts/applet/common";
4
5
import { endpoint, SharedWorker, transfer } from "@scripts/common";
5
6
import manifest from "./_manifest.json";
···
7
8
////////////////////////////////////////////
8
9
// SETUP
9
10
////////////////////////////////////////////
10
10
-
const worker = endpoint<Actions>(
11
11
+
const worker = endpoint<Tasks>(
11
12
new SharedWorker(new URL("../../../scripts/processor/metadata/worker", import.meta.url), {
12
13
type: "module",
13
14
name: manifest.name,
···
15
16
);
16
17
17
18
// Register applet
18
18
-
const context = register();
19
19
+
const context = register({ worker });
19
20
20
21
////////////////////////////////////////////
21
22
// ACTIONS
22
23
////////////////////////////////////////////
23
23
-
const supply: Actions["supply"] = (args: Parameters<Actions["supply"]>[0]) => {
24
24
-
const transferredArgs = transfer(args);
25
25
-
return worker.supply(transferredArgs);
26
26
-
};
24
24
+
async function supply(args: {
25
25
+
includeArtwork?: boolean;
26
26
+
mimeType?: string;
27
27
+
stream?: ReadableStream;
28
28
+
urls?: Urls;
29
29
+
}): Promise<Extraction> {
30
30
+
return worker.supply(transfer(args));
31
31
+
}
27
32
28
33
context.setActionHandler("supply", supply);
29
34
</script>
···
1
1
<script>
2
2
-
import type { Actions } from "@scripts/processor/search/worker";
2
2
+
import type { Tasks } from "@scripts/processor/search/worker";
3
3
import type { Track } from "@applets/core/types";
4
4
import { register } from "@scripts/applet/common";
5
5
import { endpoint, transfer } from "@scripts/common";
···
8
8
////////////////////////////////////////////
9
9
// SETUP
10
10
////////////////////////////////////////////
11
11
-
const worker = endpoint<Actions>(
11
11
+
const worker = endpoint<Tasks>(
12
12
new SharedWorker(new URL("../../../scripts/processor/search/worker", import.meta.url), {
13
13
type: "module",
14
14
name: manifest.name,
···
16
16
);
17
17
18
18
// Register applet
19
19
-
const context = register();
19
19
+
const context = register({ worker });
20
20
21
21
////////////////////////////////////////////
22
22
// ACTIONS
···
1
1
import type { Track } from "@applets/core/types.js";
2
2
import type { Item, State } from "./types";
3
3
-
import { arrayShuffle, expose, transfer } from "@scripts/common.ts";
3
3
+
import { arrayShuffle, provide, transfer } from "@scripts/common.ts";
4
4
5
5
////////////////////////////////////////////
6
6
// STATE
···
12
12
pool: [],
13
13
};
14
14
15
15
+
const state: State = {
16
16
+
future: [],
17
17
+
past: [],
18
18
+
now: null,
19
19
+
};
20
20
+
21
21
+
function data() {
22
22
+
return transfer({ ...state });
23
23
+
}
24
24
+
15
25
////////////////////////////////////////////
16
16
-
// ACTIONS
26
26
+
// SETUP
17
27
////////////////////////////////////////////
18
18
-
const actions = expose({
28
28
+
29
29
+
const actions = {
19
30
add,
20
31
pool,
21
32
shift,
22
33
unshift,
34
34
+
};
35
35
+
36
36
+
const { tasks } = provide({
37
37
+
actions,
38
38
+
tasks: actions,
23
39
});
24
40
25
41
export type Actions = typeof actions;
42
42
+
export type Tasks = typeof tasks;
26
43
27
27
-
// Actions
44
44
+
////////////////////////////////////////////
45
45
+
// ACTIONS
46
46
+
////////////////////////////////////////////
28
47
29
29
-
function add(state: State, items: Item[]): State {
30
30
-
return transfer({ ...state, future: [...state.future, ...items] });
48
48
+
function add(items: Item[]): State {
49
49
+
state.future = [...state.future, ...items];
50
50
+
51
51
+
// Fin
52
52
+
return data();
31
53
}
32
54
33
33
-
function pool(state: State, tracks: Track[]): State {
55
55
+
function pool(tracks: Track[]): State {
34
56
internal.pool = tracks;
35
57
36
58
// TODO: If the pool changes, only remove non-existing tracks
···
38
60
//
39
61
// What about past queue items?
40
62
41
41
-
state = fill({ ...state, future: [] });
63
63
+
state.future = [];
64
64
+
fill();
42
65
43
66
// Automatically insert track if there isn't any
44
44
-
if (!state.now) return shift(state);
45
45
-
return transfer(state);
67
67
+
if (!state.now) return shift();
68
68
+
69
69
+
// Fin
70
70
+
return data();
46
71
}
47
72
48
48
-
function shift(state: State): State {
49
49
-
const now = state.future[0] || null;
50
50
-
const future = state.future.slice(1);
51
51
-
const past = state.now ? [...state.past, state.now] : state.past;
52
52
-
const filled = fill({ past, now, future });
73
73
+
function shift(): State {
74
74
+
state.now = state.future[0] || null;
75
75
+
state.future = state.future.slice(1);
76
76
+
state.past = state.now ? [...state.past, state.now] : state.past;
53
77
54
54
-
return transfer(filled);
78
78
+
fill();
79
79
+
80
80
+
// Fin
81
81
+
return data();
55
82
}
56
83
57
57
-
function unshift(state: State): State {
84
84
+
function unshift(): State {
58
85
if (state.past.length === 0) return state;
59
86
60
87
const past = [...state.past];
61
88
const [last] = past.splice(past.length - 1, 1);
62
62
-
const now = last ?? null;
63
63
-
const future = state.now ? [state.now, ...state.future] : state.future;
89
89
+
state.now = last ?? null;
90
90
+
state.future = state.now ? [state.now, ...state.future] : state.future;
64
91
65
65
-
return transfer({ past, now, future });
92
92
+
// Fin
93
93
+
return data();
66
94
}
67
95
68
96
// 🛠️
69
97
70
98
// TODO: Most likely there's a more performant solution
71
71
-
function fill(state: State): State {
99
99
+
function fill() {
72
100
if (state.future.length >= QUEUE_SIZE) return state;
73
101
74
102
let reducedPool = internal.pool.reduce(
···
92
120
}
93
121
94
122
const poolSelection = arrayShuffle(reducedPool).slice(0, QUEUE_SIZE - state.future.length);
95
95
-
return add(state, poolSelection);
123
123
+
124
124
+
add(poolSelection);
96
125
}
···
1
1
import type { Extraction, Urls } from "./types.d.ts";
2
2
-
import { expose, transfer } from "@scripts/common";
2
2
+
import { provide, transfer } from "@scripts/common";
3
3
import { musicMetadataTags } from "./common.ts";
4
4
5
5
////////////////////////////////////////////
6
6
// ACTIONS
7
7
////////////////////////////////////////////
8
8
-
const actions = expose({
8
8
+
const actions = {
9
9
supply,
10
10
+
};
11
11
+
12
12
+
const { tasks } = provide({
13
13
+
actions,
14
14
+
tasks: actions,
10
15
});
11
16
12
17
export type Actions = typeof actions;
18
18
+
export type Tasks = typeof tasks;
13
19
14
20
// Actions
15
21
···
2
2
// import { pluginQPS } from "@orama/plugin-qps";
3
3
4
4
import type { Track } from "@applets/core/types";
5
5
-
import { expose, transfer } from "@scripts/common";
5
5
+
import { expose, provide, transfer } from "@scripts/common";
6
6
import { SCHEMA } from "./constants";
7
7
import type { State } from "./types";
8
8
···
52
52
// },
53
53
});
54
54
55
55
-
////////////////////////////////////////////
56
56
-
// ACTIONS
57
57
-
////////////////////////////////////////////
58
58
-
const actions = expose({
55
55
+
// 🚀
56
56
+
57
57
+
const actions = {
59
58
search,
60
59
supply,
60
60
+
};
61
61
+
62
62
+
const { tasks } = provide({
63
63
+
actions,
64
64
+
tasks: actions,
61
65
});
62
66
63
67
export type Actions = typeof actions;
68
68
+
export type Tasks = typeof tasks;
64
69
65
65
-
// Actions
70
70
+
////////////////////////////////////////////
71
71
+
// ACTIONS
72
72
+
////////////////////////////////////////////
66
73
67
74
async function search(term: string): Promise<Track[]> {
68
75
const results = await Orama.search(db, {