@misofm/sdk 0.4.0 → 0.5.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.
Files changed (48) hide show
  1. package/dist/catalog.d.ts +4 -17
  2. package/dist/catalog.d.ts.map +1 -1
  3. package/dist/catalog.js +46 -58
  4. package/dist/catalog.js.map +1 -1
  5. package/dist/cover.d.ts +10 -0
  6. package/dist/cover.d.ts.map +1 -1
  7. package/dist/cover.js +66 -19
  8. package/dist/cover.js.map +1 -1
  9. package/dist/credits.d.ts +10 -0
  10. package/dist/credits.d.ts.map +1 -1
  11. package/dist/credits.js +149 -39
  12. package/dist/credits.js.map +1 -1
  13. package/dist/drop.d.ts +7 -0
  14. package/dist/drop.d.ts.map +1 -1
  15. package/dist/drop.js +84 -34
  16. package/dist/drop.js.map +1 -1
  17. package/dist/pressing.d.ts.map +1 -1
  18. package/dist/pressing.js +59 -16
  19. package/dist/pressing.js.map +1 -1
  20. package/dist/read/artist.d.ts +1 -6
  21. package/dist/read/artist.d.ts.map +1 -1
  22. package/dist/read/artist.js +39 -22
  23. package/dist/read/artist.js.map +1 -1
  24. package/dist/read/catalog.d.ts +24 -3
  25. package/dist/read/catalog.d.ts.map +1 -1
  26. package/dist/read/catalog.js +190 -89
  27. package/dist/read/catalog.js.map +1 -1
  28. package/dist/read/index.d.ts +5 -3
  29. package/dist/read/index.d.ts.map +1 -1
  30. package/dist/read/index.js +2 -2
  31. package/dist/read/index.js.map +1 -1
  32. package/dist/read/types.d.ts +12 -1
  33. package/dist/read/types.d.ts.map +1 -1
  34. package/dist/read/works.d.ts +3 -2
  35. package/dist/read/works.d.ts.map +1 -1
  36. package/dist/read/works.js +158 -48
  37. package/dist/read/works.js.map +1 -1
  38. package/package.json +1 -1
  39. package/src/catalog.ts +71 -77
  40. package/src/cover.ts +107 -26
  41. package/src/credits.ts +353 -89
  42. package/src/drop.ts +150 -40
  43. package/src/pressing.ts +146 -36
  44. package/src/read/artist.ts +73 -34
  45. package/src/read/catalog.ts +324 -89
  46. package/src/read/index.ts +23 -2
  47. package/src/read/types.ts +16 -2
  48. package/src/read/works.ts +224 -59
@@ -9,19 +9,21 @@
9
9
  // out from the browser (`lib/party-queries.ts`, plus a second identical fan-out in
10
10
  // `PartyEditSheet`). Here they are one call, resolved once, cached once.
11
11
  //
12
- // `roles` and `tags` are opt-in via `include`: only the owner's edit sheet reads
13
- // them, and leaving them out of the public read keeps the hot path to six.
12
+ // `roles`, `tags`, and the resolved featured release are opt-in via `include`.
14
13
 
15
14
  import { resolveGenreNames } from "./genres.ts";
16
- import { readReleaseCover } from "./catalog.ts";
15
+ import { getReleaseResources } from "./catalog.ts";
17
16
  import { getDrop } from "../drop.ts";
18
- import { getReleaseById } from "@misonetwork/sdk";
19
- import { getReleaseCredits } from "../credits.ts";
20
17
  import type { MisoClient } from "./client.ts";
21
- import type { ArtistProfile, FeaturedRelease, PartyMember, PartySummary } from "./types.ts";
18
+ import type {
19
+ ArtistProfile,
20
+ FeaturedRelease,
21
+ PartyMember,
22
+ PartySummary,
23
+ } from "./types.ts";
22
24
 
23
25
  /** Optional sub-resources — read only when asked for. */
24
- export type ArtistInclude = "roles" | "tags";
26
+ export type ArtistInclude = "roles" | "tags" | "featured";
25
27
 
26
28
  export interface GetArtistOptions {
27
29
  include?: readonly ArtistInclude[];
@@ -45,22 +47,30 @@ export async function getArtistProfile(
45
47
  const include = new Set(options.include ?? []);
46
48
  const { party } = client.sui;
47
49
 
48
- const [profile, ctas, genreIds, links, roles, tags] = await Promise.all([
49
- party.getProfile(partyId).catch(() => null),
50
- party.getCtas(partyId).catch(() => []),
51
- party.getGenres(partyId).catch(() => [] as string[]),
52
- party.getLinks(partyId).catch(() => []),
53
- include.has("roles") ? party.getRoles(partyId).catch(() => [] as string[]) : Promise.resolve(undefined),
54
- include.has("tags") ? party.getTags(partyId).catch(() => [] as string[]) : Promise.resolve(undefined),
55
- ]);
56
-
57
- // The party read is the one that may legitimately fail (no such party), so it
58
- // is awaited on its own rather than being swallowed by the batch above.
59
- const entity = await party.getPartyById(partyId);
60
-
61
- const [genres, members] = await Promise.all([
50
+ const [profile, ctas, genreIds, links, roles, tags, entity] =
51
+ await Promise.all([
52
+ party.getProfile(partyId).catch(() => null),
53
+ party.getCtas(partyId).catch(() => []),
54
+ party.getGenres(partyId).catch(() => [] as string[]),
55
+ party.getLinks(partyId).catch(() => []),
56
+ include.has("roles")
57
+ ? party.getRoles(partyId).catch(() => [] as string[])
58
+ : Promise.resolve(undefined),
59
+ include.has("tags")
60
+ ? party.getTags(partyId).catch(() => [] as string[])
61
+ : Promise.resolve(undefined),
62
+ party.getPartyById(partyId),
63
+ ]);
64
+
65
+ const [genres, members, featured] = await Promise.all([
62
66
  resolveGenreNames(client, genreIds),
63
- resolveMembers(client, entity.kind === "group" ? (entity.members ?? []) : []),
67
+ resolveMembers(
68
+ client,
69
+ entity.kind === "group" ? (entity.members ?? []) : [],
70
+ ),
71
+ include.has("featured")
72
+ ? resolveFeaturedRelease(client, partyId, entity.name).catch(() => null)
73
+ : Promise.resolve(undefined),
64
74
  ]);
65
75
 
66
76
  return {
@@ -73,19 +83,29 @@ export async function getArtistProfile(
73
83
  country: profile?.country ?? null,
74
84
  languages: profile?.languages ?? [],
75
85
  genres,
76
- links: links.map((l) => ({ platform: l.platform, value: l.value, url: l.url })),
86
+ links: links.map((l) => ({
87
+ platform: l.platform,
88
+ value: l.value,
89
+ url: l.url,
90
+ })),
77
91
  ctas: ctas.map((c) => ({ label: c.label, url: c.url })),
78
92
  members,
79
93
  ...(roles !== undefined ? { roles } : {}),
80
94
  ...(tags !== undefined ? { tags } : {}),
95
+ ...(featured !== undefined ? { featured } : {}),
81
96
  avatarUrl: partyAvatarUrl(client.config.apiBaseUrl, entity.id),
82
97
  };
83
98
  }
84
99
 
85
100
  /** Group members with names resolved. A member that fails to read is dropped. */
86
- async function resolveMembers(client: MisoClient, memberIds: readonly string[]): Promise<PartyMember[]> {
101
+ async function resolveMembers(
102
+ client: MisoClient,
103
+ memberIds: readonly string[],
104
+ ): Promise<PartyMember[]> {
87
105
  if (memberIds.length === 0) return [];
88
- const parties = await client.sui.party.getPartiesByIds([...memberIds]).catch(() => ({}) as Record<string, undefined>);
106
+ const parties = await client.sui.party
107
+ .getPartiesByIds([...memberIds])
108
+ .catch(() => ({}) as Record<string, undefined>);
89
109
  return memberIds.flatMap((id) => {
90
110
  const p = parties[id];
91
111
  return p ? [{ id, name: p.name }] : [];
@@ -93,7 +113,10 @@ async function resolveMembers(client: MisoClient, memberIds: readonly string[]):
93
113
  }
94
114
 
95
115
  /** Name + kind for many parties at once. Ids that don't resolve are omitted. */
96
- export async function getPartySummaries(client: MisoClient, ids: readonly string[]): Promise<PartySummary[]> {
116
+ export async function getPartySummaries(
117
+ client: MisoClient,
118
+ ids: readonly string[],
119
+ ): Promise<PartySummary[]> {
97
120
  if (ids.length === 0) return [];
98
121
  const parties = await client.sui.party.getPartiesByIds([...ids]);
99
122
  return ids.flatMap((id) => {
@@ -107,30 +130,46 @@ export async function getPartySummaries(client: MisoClient, ids: readonly string
107
130
  * `null` — a successful empty — when nothing is pinned or the pin is dangling
108
131
  * (the pressing it named has since been superseded and destroyed).
109
132
  */
110
- export async function getFeaturedRelease(client: MisoClient, partyId: string): Promise<FeaturedRelease | null> {
133
+ async function resolveFeaturedRelease(
134
+ client: MisoClient,
135
+ partyId: string,
136
+ fallbackArtist?: string,
137
+ ): Promise<FeaturedRelease | null> {
111
138
  const pressingId = await client.sui.party.getFeaturedDrop(partyId);
112
139
  if (!pressingId) return null;
113
140
 
114
141
  const pressing = await getDrop(client.protocol, pressingId);
115
142
  if (!pressing) return null;
116
143
 
117
- const [release, cover, credits, entity] = await Promise.all([
118
- getReleaseById(client.protocol, pressing.releaseId),
119
- readReleaseCover(client, pressing.releaseId),
120
- getReleaseCredits(client.protocol, pressing.releaseId, client.config.protocol.releaseCredits).catch(() => null),
121
- client.sui.party.getPartyById(partyId),
144
+ const [resources, entity] = await Promise.all([
145
+ getReleaseResources(client, pressing.releaseId, ["cover", "credits"]),
146
+ fallbackArtist === undefined
147
+ ? client.sui.party.getPartyById(partyId)
148
+ : Promise.resolve(null),
122
149
  ]);
150
+ const { release, cover, credits } = resources;
123
151
 
124
152
  // The artist line prefers the release's own PRIMARY credits and falls back to
125
153
  // the party whose page this is — a release with no credits set still shows an
126
154
  // artist, which is the behavior the featured card has always had.
127
- const primary = (credits ?? []).filter((c) => c.roles.includes("Primary")).map((c) => c.displayName);
155
+ const primary = (credits ?? [])
156
+ .filter((c) => c.roles.includes("Primary"))
157
+ .map((c) => c.displayName);
128
158
 
129
159
  return {
130
160
  pressingId,
131
161
  releaseId: pressing.releaseId,
132
162
  title: release.title,
133
- artist: primary.length ? primary.join(", ") : entity.name,
163
+ artist: primary.length
164
+ ? primary.join(", ")
165
+ : (fallbackArtist ?? entity?.name ?? ""),
134
166
  coverUrl: cover?.still.url ?? null,
135
167
  };
136
168
  }
169
+
170
+ export async function getFeaturedRelease(
171
+ client: MisoClient,
172
+ partyId: string,
173
+ ): Promise<FeaturedRelease | null> {
174
+ return resolveFeaturedRelease(client, partyId);
175
+ }