@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
@@ -1,67 +1,172 @@
1
1
  // Copyright (c) Miso Labs, Inc.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
- import { extractTypeParams2, getCompositionsByIds, getRecordingsByIds, getReleasesByIds, } from "@misonetwork/sdk";
4
- /** Resolve work share types without relying on unpublished protocol helpers. */
3
+ import { normalizeSuiAddress } from "@mysten/sui/utils";
4
+ import { contracts, extractTypeParams2, getCompositionsByIds, } from "@misonetwork/sdk";
5
+ /** Resolve all work share types in one aliased GraphQL request. */
5
6
  export async function getWorkAddressesByShareTypes(client, shareTypes, misoPackageId) {
6
7
  const compositions = [...new Set(shareTypes.compositions)];
7
- const recordingSet = new Set(shareTypes.recordings);
8
+ const recordings = new Set(shareTypes.recordings);
8
9
  const out = { compositions: {}, recordings: {} };
9
- const compositionEntries = await Promise.all(compositions.map(async (shareType) => {
10
- const type = `${misoPackageId}::composition::Composition<${shareType}>`;
11
- const result = await client.query({
12
- query: `query WorkByType($type: String!) {
13
- objects(filter: { type: $type }) {
14
- nodes { address asMoveObject { contents { type { repr } } } }
15
- }
16
- }`,
17
- variables: { type },
18
- });
19
- if (result.errors?.length)
20
- throw new Error(result.errors[0].message);
21
- return [shareType, result.data?.objects?.nodes[0]?.address];
22
- }));
23
- for (const [shareType, address] of compositionEntries) {
10
+ if (compositions.length === 0 && recordings.size === 0)
11
+ return out;
12
+ const declarations = [];
13
+ const selections = [];
14
+ const variables = {};
15
+ compositions.forEach((shareType, index) => {
16
+ const variable = `compositionType${index}`;
17
+ declarations.push(`$${variable}: String!`);
18
+ selections.push(`composition${index}: objects(first: 1, filter: { type: $${variable} }) { nodes { address } }`);
19
+ variables[variable] =
20
+ `${misoPackageId}::composition::Composition<${shareType}>`;
21
+ });
22
+ if (recordings.size > 0) {
23
+ declarations.push("$recordingType: String!");
24
+ selections.push(`recordings: objects(first: 50, filter: { type: $recordingType }) {
25
+ pageInfo { hasNextPage endCursor }
26
+ nodes { address asMoveObject { contents { type { repr } } } }
27
+ }`);
28
+ variables.recordingType = `${misoPackageId}::recording::Recording`;
29
+ }
30
+ const result = await client.query({
31
+ query: `query WorkAddressesByShareTypes(${declarations.join(", ")}) {
32
+ ${selections.join("\n")}
33
+ }`,
34
+ variables,
35
+ });
36
+ if (result.errors?.length) {
37
+ throw new AggregateError(result.errors.map((error) => new Error(error.message)), "Work type discovery failed");
38
+ }
39
+ compositions.forEach((shareType, index) => {
40
+ const address = result.data?.[`composition${index}`]?.nodes[0]?.address;
24
41
  if (address)
25
42
  out.compositions[shareType] = address;
26
- }
27
- if (recordingSet.size > 0) {
28
- const type = `${misoPackageId}::recording::Recording`;
29
- const result = await client.query({
30
- query: `query RecordingsByType($type: String!) {
31
- objects(filter: { type: $type }) {
32
- nodes { address asMoveObject { contents { type { repr } } } }
33
- }
34
- }`,
35
- variables: { type },
36
- });
37
- if (result.errors?.length)
38
- throw new Error(result.errors[0].message);
39
- for (const node of result.data?.objects?.nodes ?? []) {
40
- const repr = node.asMoveObject?.contents?.type.repr;
43
+ });
44
+ const readRecordingPage = (page) => {
45
+ for (const node of page?.nodes ?? []) {
46
+ const repr = node.asMoveObject?.contents?.type?.repr;
41
47
  if (!repr)
42
48
  continue;
43
- let recordingShareType;
44
49
  try {
45
- [recordingShareType] = extractTypeParams2(repr);
50
+ const [shareType] = extractTypeParams2(repr);
51
+ if (recordings.has(shareType))
52
+ out.recordings[shareType] = node.address;
46
53
  }
47
54
  catch {
48
- recordingShareType = /<(.+)>$/.exec(repr)?.[1]?.trim();
49
- }
50
- if (recordingShareType && recordingSet.has(recordingShareType)) {
51
- out.recordings[recordingShareType] = node.address;
55
+ // Ignore objects whose deployed type does not match the Recording ABI.
52
56
  }
53
57
  }
58
+ };
59
+ let page = result.data?.recordings;
60
+ readRecordingPage(page);
61
+ while (page?.pageInfo?.hasNextPage &&
62
+ page.pageInfo.endCursor &&
63
+ Object.keys(out.recordings).length < recordings.size) {
64
+ const next = await client.query({
65
+ query: `query RecordingWorkAddresses($recordingType: String!, $cursor: String!) {
66
+ recordings: objects(first: 50, after: $cursor, filter: { type: $recordingType }) {
67
+ pageInfo { hasNextPage endCursor }
68
+ nodes { address asMoveObject { contents { type { repr } } } }
69
+ }
70
+ }`,
71
+ variables: {
72
+ recordingType: variables.recordingType,
73
+ cursor: page.pageInfo.endCursor,
74
+ },
75
+ });
76
+ if (next.errors?.length) {
77
+ throw new AggregateError(next.errors.map((error) => new Error(error.message)), "Recording type discovery failed");
78
+ }
79
+ page = next.data?.recordings;
80
+ readRecordingPage(page);
54
81
  }
55
82
  return out;
56
83
  }
57
- /** Fetch each work kind through the authoritative protocol SDK. */
84
+ function workState(value) {
85
+ return value?.$kind === "Published"
86
+ ? { type: "Published", timestampMs: Number(value.Published) }
87
+ : { type: "Initialized" };
88
+ }
89
+ function parseComposition(id, content) {
90
+ const value = contracts.composition.Composition.parse(content);
91
+ return {
92
+ id,
93
+ state: workState(value.state),
94
+ title: String(value.title),
95
+ royaltyRate: {
96
+ value: Number(Array.isArray(value.royalty_rate)
97
+ ? value.royalty_rate[0]
98
+ : value.royalty_rate),
99
+ },
100
+ };
101
+ }
102
+ function parseRecording(id, content) {
103
+ const value = contracts.recording.Recording.parse(content);
104
+ return { id, state: workState(value.state) };
105
+ }
106
+ export function parseReleaseObject(id, content, json) {
107
+ const deployed = json;
108
+ if (deployed?.discs) {
109
+ const tracks = deployed.discs.flatMap((disc) => disc.tracks ?? []);
110
+ const publishedAt = deployed.state?.["@variant"] === "Published" ? deployed.state.pos0 : null;
111
+ return {
112
+ id,
113
+ state: publishedAt == null
114
+ ? { type: "Initialized" }
115
+ : { type: "Published", timestampMs: Number(publishedAt) },
116
+ title: String(deployed.title ?? ""),
117
+ tracks: tracks.map((track) => ({
118
+ state: (track.state?.["@variant"] ?? "Unassigned"),
119
+ recordingId: String(track.recording_id),
120
+ splitBps: { value: Number(track.split_bps?.pos0 ?? track.split_bps) },
121
+ })),
122
+ };
123
+ }
124
+ const value = contracts.release.Release.parse(content);
125
+ return {
126
+ id,
127
+ state: workState(value.state),
128
+ title: String(value.title),
129
+ tracks: (value.tracks ?? []).map((track) => ({
130
+ state: (track.state?.$kind ?? "Unassigned"),
131
+ recordingId: String(track.recording_id),
132
+ splitBps: {
133
+ value: Number(Array.isArray(track.split_bps) ? track.split_bps[0] : track.split_bps),
134
+ },
135
+ })),
136
+ };
137
+ }
138
+ /** Fetch and parse heterogeneous works through one Core bulk request. */
58
139
  export async function getWorksByIds(client, ids) {
59
- const [compositions, recordings, releases] = await Promise.all([
60
- getCompositionsByIds(client, [...ids.compositions]),
61
- getRecordingsByIds(client, [...ids.recordings]),
62
- getReleasesByIds(client, [...ids.releases]),
63
- ]);
64
- return { compositions, recordings, releases };
140
+ const kinds = new Map();
141
+ for (const [kind, objectIds] of Object.entries(ids)) {
142
+ for (const objectId of objectIds) {
143
+ const normalized = normalizeSuiAddress(objectId);
144
+ const previous = kinds.get(normalized);
145
+ if (previous && previous !== kind) {
146
+ throw new Error(`Work ${normalized} was requested as both ${previous} and ${kind}`);
147
+ }
148
+ kinds.set(normalized, kind);
149
+ }
150
+ }
151
+ const out = { compositions: {}, recordings: {}, releases: {} };
152
+ if (kinds.size === 0)
153
+ return out;
154
+ const { objects } = await client.core.getObjects({
155
+ objectIds: [...kinds.keys()],
156
+ include: { content: true, json: true },
157
+ });
158
+ for (const object of objects) {
159
+ if (object instanceof Error || !object.content)
160
+ continue;
161
+ const kind = kinds.get(normalizeSuiAddress(object.objectId));
162
+ if (kind === "compositions")
163
+ out.compositions[object.objectId] = parseComposition(object.objectId, object.content);
164
+ else if (kind === "recordings")
165
+ out.recordings[object.objectId] = parseRecording(object.objectId, object.content);
166
+ else if (kind === "releases")
167
+ out.releases[object.objectId] = parseReleaseObject(object.objectId, object.content, object.json);
168
+ }
169
+ return out;
65
170
  }
66
171
  /**
67
172
  * Resolve display titles for both deployed recording layouts. Older recordings
@@ -71,7 +176,10 @@ export async function getRecordingTitles(client, graphql, recordingIds, misoPack
71
176
  const ids = [...new Set(recordingIds)];
72
177
  if (ids.length === 0)
73
178
  return {};
74
- const { objects } = await client.core.getObjects({ objectIds: ids, include: { json: true } });
179
+ const { objects } = await client.core.getObjects({
180
+ objectIds: ids,
181
+ include: { json: true },
182
+ });
75
183
  const titles = {};
76
184
  const compositionShareByRecording = {};
77
185
  for (const object of objects) {
@@ -97,7 +205,9 @@ export async function getRecordingTitles(client, graphql, recordingIds, misoPack
97
205
  const compositions = await getCompositionsByIds(client, Object.values(addresses.compositions).filter((id) => !!id));
98
206
  for (const [recordingId, shareType] of Object.entries(compositionShareByRecording)) {
99
207
  const compositionId = addresses.compositions[shareType];
100
- const title = compositionId ? compositions[compositionId]?.title : undefined;
208
+ const title = compositionId
209
+ ? compositions[compositionId]?.title
210
+ : undefined;
101
211
  if (title)
102
212
  titles[recordingId] = title;
103
213
  }
@@ -1 +1 @@
1
- {"version":3,"file":"works.js","sourceRoot":"","sources":["../../src/read/works.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"works.js","sourceRoot":"","sources":["../../src/read/works.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@misofm/sdk",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Complete client SDK for the Miso platform on Sui \u2014 high-level reads, pressings, listings, records, and work publishing.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
package/src/catalog.ts CHANGED
@@ -14,16 +14,16 @@
14
14
  import type { ClientWithCoreApi } from "@mysten/sui/client";
15
15
  import type { SuiGraphQLClient } from "@mysten/sui/graphql";
16
16
  import {
17
- getCompositionAddressByShareType,
17
+ extractTypeParams2,
18
18
  getOwnedRecordingAdminCaps,
19
- getRecordingByShareType,
20
- getRecordingShareTypes,
19
+ getRecordingsByIds,
21
20
  getReleaseById,
22
21
  type Recording,
23
22
  } from "@misonetwork/sdk";
23
+ import { getWorkAddressesByShareTypes } from "./read/works.ts";
24
24
  import {
25
- getCompositionCredits,
26
- getRecordingCredits,
25
+ getCompositionCreditsByIds,
26
+ getRecordingCreditsByIds,
27
27
  type CreditView,
28
28
  type RecordingCreditsView,
29
29
  } from "./credits.ts";
@@ -85,51 +85,60 @@ export async function getTrackCreditsByRecordingIds(
85
85
  options: GetReleaseTrackCreditsOptions,
86
86
  ): Promise<Record<string, ReleaseTrackCredits>> {
87
87
  const recordingIds = [...new Set(recordingIdsInput)];
88
+ if (recordingIds.length === 0) return {};
88
89
 
89
- const recordingReads = await Promise.all(
90
- recordingIds.map(async (recordingId) => {
91
- const [recordingCredits, [, compositionShareType]] = await Promise.all([
92
- getRecordingCredits(client, recordingId, options.recordingCreditsPackageId),
93
- getRecordingShareTypes(client, recordingId),
94
- ]);
95
- return { recordingId, recordingCredits, compositionShareType };
96
- }),
97
- );
90
+ const [recordingCreditsById, recordingObjects] = await Promise.all([
91
+ getRecordingCreditsByIds(
92
+ client,
93
+ recordingIds,
94
+ options.recordingCreditsPackageId,
95
+ ),
96
+ client.core.getObjects({ objectIds: recordingIds }),
97
+ ]);
98
+ const recordingReads = recordingObjects.objects.map((object, index) => {
99
+ const recordingId = recordingIds[index]!;
100
+ if (object instanceof Error) throw object;
101
+ const [, compositionShareType] = extractTypeParams2(object.type);
102
+ return {
103
+ recordingId,
104
+ recordingCredits: recordingCreditsById[recordingId] ?? null,
105
+ compositionShareType,
106
+ };
107
+ });
98
108
 
99
- const compositionShareTypes = [...new Set(recordingReads.map((read) => read.compositionShareType))];
100
- const compositionAddressEntries = await Promise.all(
101
- compositionShareTypes.map(async (shareType) => {
102
- const compositionId = await getCompositionAddressByShareType(
103
- graphqlClient,
104
- shareType,
105
- options.misoPackageId,
106
- );
107
- if (!compositionId) throw new Error(`Composition not found for share type: ${shareType}`);
108
- return [shareType, compositionId] as const;
109
- }),
109
+ const compositionShareTypes = [
110
+ ...new Set(recordingReads.map((read) => read.compositionShareType)),
111
+ ];
112
+ const addresses = await getWorkAddressesByShareTypes(
113
+ graphqlClient,
114
+ { compositions: compositionShareTypes, recordings: [] },
115
+ options.misoPackageId,
110
116
  );
111
- const compositionAddressByShareType = new Map(compositionAddressEntries);
112
-
113
- const compositionIds = [...new Set(compositionAddressEntries.map(([, compositionId]) => compositionId))];
114
- const compositionCreditEntries = await Promise.all(
115
- compositionIds.map(async (compositionId) => {
116
- const credits = await getCompositionCredits(
117
- client,
118
- compositionId,
119
- options.compositionCreditsPackageId,
120
- );
121
- return [compositionId, credits ?? []] as const;
122
- }),
117
+ for (const shareType of compositionShareTypes) {
118
+ if (!addresses.compositions[shareType]) {
119
+ throw new Error(`Composition not found for share type: ${shareType}`);
120
+ }
121
+ }
122
+ const compositionIds = [
123
+ ...new Set(
124
+ Object.values(addresses.compositions).filter(
125
+ (id): id is string => id !== undefined,
126
+ ),
127
+ ),
128
+ ];
129
+ const compositionCreditsById = await getCompositionCreditsByIds(
130
+ client,
131
+ compositionIds,
132
+ options.compositionCreditsPackageId,
123
133
  );
124
- const compositionCreditsById = new Map(compositionCreditEntries);
125
134
 
126
135
  return Object.fromEntries(
127
136
  recordingReads.map((read) => {
128
- const compositionId = compositionAddressByShareType.get(read.compositionShareType)!;
137
+ const compositionId = addresses.compositions[read.compositionShareType]!;
129
138
  return [
130
139
  read.recordingId,
131
140
  {
132
- compositionCredits: compositionCreditsById.get(compositionId) ?? [],
141
+ compositionCredits: compositionCreditsById[compositionId] ?? [],
133
142
  recordingCredits: read.recordingCredits ?? EMPTY_RECORDING_CREDITS,
134
143
  },
135
144
  ];
@@ -139,9 +148,8 @@ export async function getTrackCreditsByRecordingIds(
139
148
 
140
149
  export interface GetAdministeredRecordingsOptions {
141
150
  /**
142
- * Maximum lookups in flight at once. The traversal is one lookup per admin
143
- * cap, so an artist with a large catalog would otherwise open as many
144
- * concurrent requests as they have recordings. Defaults to 10.
151
+ * @deprecated Resolution is batched; this option is retained for source
152
+ * compatibility and no longer affects request concurrency.
145
153
  */
146
154
  concurrency?: number;
147
155
  }
@@ -149,20 +157,8 @@ export interface GetAdministeredRecordingsOptions {
149
157
  /**
150
158
  * Every `Recording` administered by `owner`.
151
159
  *
152
- * Two stages: list the owner's `RecordingAdminCap`s over the Core API, then
153
- * resolve each cap's share type back to its recording.
154
- *
155
- * The second stage needs GraphQL and is inherently one lookup per cap, because
156
- * `RecordingAdminCap` carries no back-pointer to its recording — unlike
157
- * `ReleaseAdminCap`, which stores `release_id` and can therefore be resolved
158
- * entirely over the Core API. The caps are derived objects (recording → cap via
159
- * `deriveObjectID`), and that derivation cannot be inverted, so the share type
160
- * is the only link back. Adding a `recording_id: ID` field to
161
- * `RecordingAdminCap` on the protocol side would make this a pure Core-API
162
- * batch read and remove both the GraphQL dependency and the fan-out.
163
- *
164
- * Until then the lookups run concurrently in bounded batches rather than
165
- * serially.
160
+ * Three bounded stages: list the owner's `RecordingAdminCap`s, resolve every
161
+ * share type in one aliased GraphQL query, then batch-fetch the recordings.
166
162
  */
167
163
  export async function getAdministeredRecordings(
168
164
  client: ClientWithCoreApi,
@@ -171,25 +167,23 @@ export async function getAdministeredRecordings(
171
167
  misoPackageId: string,
172
168
  options: GetAdministeredRecordingsOptions = {},
173
169
  ): Promise<Recording[]> {
174
- const concurrency = Math.max(1, options.concurrency ?? 10);
170
+ void options;
175
171
  const caps = await getOwnedRecordingAdminCaps(client, owner, misoPackageId);
176
-
177
- const recordings: Recording[] = [];
178
- for (let i = 0; i < caps.length; i += concurrency) {
179
- const batch = caps.slice(i, i + concurrency);
180
- const settled = await Promise.all(
181
- batch.map(async (cap) => {
182
- try {
183
- return await getRecordingByShareType(client, graphqlClient, cap.shareType, misoPackageId);
184
- } catch {
185
- // A cap whose recording cannot be resolved is skipped rather than
186
- // failing the whole catalog — matching the previous behavior, where a
187
- // missing address was silently passed over.
188
- return null;
189
- }
190
- }),
191
- );
192
- for (const rec of settled) if (rec) recordings.push(rec);
193
- }
194
- return recordings;
172
+ if (caps.length === 0) return [];
173
+ const addresses = await getWorkAddressesByShareTypes(
174
+ graphqlClient,
175
+ { compositions: [], recordings: caps.map((cap) => cap.shareType) },
176
+ misoPackageId,
177
+ );
178
+ const byId = await getRecordingsByIds(
179
+ client,
180
+ Object.values(addresses.recordings).filter(
181
+ (id): id is string => id !== undefined,
182
+ ),
183
+ );
184
+ return caps.flatMap((cap) => {
185
+ const id = addresses.recordings[cap.shareType];
186
+ const recording = id ? byId[id] : undefined;
187
+ return recording ? [recording] : [];
188
+ });
195
189
  }