alpha
Login
or
Join now
tokono.ma
/
diffuse-applets
Star
0
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Experiment to rebuild Diffuse using web applets.
Star
0
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Overview
Issues
Pulls
Pipelines
fix: only save tracks when changed
author
Steven Vandevelde
date
11 months ago
(Jul 2, 2025, 2:37 PM +0200)
commit
0cdff63c
0cdff63c35adc79f618bbecc189a36f34918ee0f
parent
3dd4ce9e
3dd4ce9e86a0e7ccc829072332a142750b7f0ff7
+33
-21
4 changed files
Expand all
Collapse all
Unified
Split
src
pages
orchestrator
input-cache
_applet.astro
output
storacha-automerge
_applet.astro
scripts
input
opensubsonic
worker.ts
output
common.ts
+8
-10
src/pages/orchestrator/input-cache/_applet.astro
Reviewed
···
1
1
<script>
2
2
import type { ManagedOutput, ResolvedUri, Track } from "@applets/core/types.d.ts";
3
3
import { applet, register, wait } from "@scripts/applet/common";
4
4
+
import { tracksCacheId } from "@scripts/output/common";
4
5
5
6
////////////////////////////////////////////
6
7
// SETUP
···
23
24
};
24
25
25
26
// Start processing once settled and tracks are loaded
26
26
-
// context
27
27
-
// .settled()
28
28
-
// .then(() => configurator.output)
29
29
-
// .then((output) => wait(output, (d) => d?.tracks.state === "loaded"))
30
30
-
// .then(() => (context.isMainInstance() ? process() : undefined));
27
27
+
context
28
28
+
.settled()
29
29
+
.then(() => configurator.output)
30
30
+
.then((output) => wait(output, (d) => d?.tracks.state === "loaded"))
31
31
+
.then(() => (context.isMainInstance() ? process() : undefined));
31
32
32
33
////////////////////////////////////////////
33
34
// ACTIONS
···
53
54
});
54
55
55
56
// Process
56
56
-
let changed = true; // TODO
57
57
-
58
57
const tracksWithMetadata = await tracks.reduce(
59
58
async (promise: Promise<Track[]>, track: Track) => {
60
59
const acc = await promise;
···
88
87
},
89
88
);
90
89
91
91
-
console.log(stats, tags);
92
92
-
changed = true;
93
93
-
94
90
return [...acc, { ...track, stats, tags }];
95
91
},
96
92
Promise.resolve([]),
97
93
);
98
94
99
95
// Save
96
96
+
const changed = tracksCacheId(tracksWithMetadata) !== output.data.tracks.cacheId;
97
97
+
100
98
if (changed)
101
99
await output.sendAction("tracks", tracksWithMetadata, {
102
100
timeoutDuration: 60000 * 5,
+2
-2
src/pages/output/storacha-automerge/_applet.astro
Reviewed
···
5
5
6
6
import type { ManagedOutput, Track } from "@applets/core/types.d.ts";
7
7
import { register } from "@scripts/applet/common";
8
8
-
import { INITIAL_MANAGED_OUTPUT } from "@scripts/output/common";
8
8
+
import { INITIAL_MANAGED_OUTPUT, tracksCacheId } from "@scripts/output/common";
9
9
import { cleanUndefinedValuesForTracks } from "@scripts/common";
10
10
11
11
////////////////////////////////////////////
···
61
61
tracks: {
62
62
...context.data.tracks,
63
63
...trackDocument,
64
64
-
cacheId: crypto.randomUUID(),
64
64
+
cacheId: tracksCacheId(context.data.tracks.collection),
65
65
state: "loaded",
66
66
},
67
67
};
+12
-6
src/scripts/input/opensubsonic/worker.ts
Reviewed
···
1
1
import { SubsonicAPI, type Child } from "subsonic-api";
2
2
import * as URI from "uri-js";
3
3
-
import QS from "query-string";
4
3
5
4
import type { Consult, ConsultGrouping, GroupConsult, Track } from "@applets/core/types.d.ts";
6
5
import { SCHEME } from "./constants.ts";
···
72
71
const parsed = parseURI(t.uri);
73
72
if (!parsed || !parsed.path) return acc;
74
73
75
75
-
const bid = serverId(parsed?.server);
76
76
-
const trk = { [parsed.path]: t };
74
74
+
const sid = serverId(parsed?.server);
75
75
+
const trk = { [URI.unescapeComponent(parsed.path)]: t };
77
76
78
78
-
return { ...acc, [bid]: acc[bid] ? { ...acc[bid], ...trk } : trk };
77
77
+
return { ...acc, [sid]: acc[sid] ? { ...acc[sid], ...trk } : trk };
79
78
}, {});
80
79
81
80
async function search(client: SubsonicAPI, offset = 0): Promise<Child[]> {
···
100
99
const servers = await loadServers();
101
100
const promises = Object.values(servers).map(async (server) => {
102
101
const client = createClient(server);
102
102
+
const sid = serverId(server);
103
103
const list = await search(client, 0);
104
104
105
105
return list
106
106
.filter((song) => !song.isVideo)
107
107
.map((song) => {
108
108
-
if (song.path && cache[song.path]) return cache[song.path];
108
108
+
const path = song.path
109
109
+
? song.path.startsWith("/")
110
110
+
? song.path
111
111
+
: `/${song.path}`
112
112
+
: undefined;
113
113
+
const fromCache = path ? cache[sid]?.[path] : undefined;
114
114
+
if (fromCache) return fromCache;
109
115
110
116
const track: Track = {
111
117
id: crypto.randomUUID(),
112
118
kind: autoTypeToTrackKind(song.type),
113
113
-
uri: buildURI(server, { songId: song.id, path: song.path }),
119
119
+
uri: buildURI(server, { songId: song.id, path }),
114
120
115
121
stats: {
116
122
bitrate: song.bitRate,
+11
-3
src/scripts/output/common.ts
Reviewed
···
1
1
+
import { xxh32r } from "xxh32/dist/raw.js";
2
2
+
1
3
import type { ManagedOutput, Track } from "@applets/core/types";
2
4
import type { BroadcastedApplet } from "@scripts/applet/common";
5
5
+
import { jsonEncode } from "@scripts/common";
3
6
4
7
export const INITIAL_MANAGED_OUTPUT: ManagedOutput = {
5
8
tracks: {
6
6
-
cacheId: crypto.randomUUID(),
9
9
+
cacheId: tracksCacheId([]),
7
10
state: "loading",
8
11
collection: [],
9
12
},
···
32
35
context.data = {
33
36
...context.data,
34
37
tracks: {
35
35
-
cacheId: crypto.randomUUID(),
38
38
+
cacheId: tracksCacheId(collection),
36
39
state: "loaded",
37
40
collection,
38
41
},
···
49
52
context.data = {
50
53
...context.data,
51
54
tracks: {
52
52
-
cacheId: crypto.randomUUID(),
55
55
+
cacheId: tracksCacheId(tracks),
53
56
state: "loaded",
54
57
collection: tracks,
55
58
},
···
67
70
tracks,
68
71
};
69
72
}
73
73
+
74
74
+
export function tracksCacheId(tracks: Track[]): string {
75
75
+
// TODO: Probably should work with encoded tracks directly?
76
76
+
return xxh32r(jsonEncode(tracks)).toString();
77
77
+
}