@misofm/musicos 0.2.0 → 0.3.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 (50) hide show
  1. package/README.md +90 -13
  2. package/dist/client.d.ts +27 -26
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +58 -51
  5. package/dist/client.js.map +1 -1
  6. package/dist/deployments.d.ts +9 -0
  7. package/dist/deployments.d.ts.map +1 -1
  8. package/dist/deployments.js +14 -0
  9. package/dist/deployments.js.map +1 -1
  10. package/dist/errors.d.ts +10 -0
  11. package/dist/errors.d.ts.map +1 -0
  12. package/dist/errors.js +17 -0
  13. package/dist/errors.js.map +1 -0
  14. package/dist/events.d.ts +6 -1
  15. package/dist/events.d.ts.map +1 -1
  16. package/dist/events.js +0 -5
  17. package/dist/events.js.map +1 -1
  18. package/dist/execute.d.ts +1 -48
  19. package/dist/execute.d.ts.map +1 -1
  20. package/dist/execute.js +5 -106
  21. package/dist/execute.js.map +1 -1
  22. package/dist/internal.d.ts +45 -6
  23. package/dist/internal.d.ts.map +1 -1
  24. package/dist/internal.js.map +1 -1
  25. package/dist/queries.d.ts +38 -62
  26. package/dist/queries.d.ts.map +1 -1
  27. package/dist/queries.js +240 -266
  28. package/dist/queries.js.map +1 -1
  29. package/dist/transactions.d.ts +2 -1
  30. package/dist/transactions.d.ts.map +1 -1
  31. package/dist/transactions.js.map +1 -1
  32. package/dist/types.d.ts +129 -79
  33. package/dist/types.d.ts.map +1 -1
  34. package/dist/types.js +169 -1
  35. package/dist/types.js.map +1 -1
  36. package/dist/view.d.ts +3 -2
  37. package/dist/view.d.ts.map +1 -1
  38. package/dist/view.js +19 -6
  39. package/dist/view.js.map +1 -1
  40. package/package.json +8 -1
  41. package/src/client.ts +78 -98
  42. package/src/deployments.ts +15 -0
  43. package/src/errors.ts +30 -0
  44. package/src/events.ts +1 -1
  45. package/src/execute.ts +5 -133
  46. package/src/internal.ts +17 -23
  47. package/src/queries.ts +386 -424
  48. package/src/transactions.ts +2 -1
  49. package/src/types.ts +59 -48
  50. package/src/view.ts +23 -9
@@ -33,6 +33,7 @@ import {
33
33
  Transaction,
34
34
  type TransactionObjectArgument,
35
35
  } from "@mysten/sui/transactions";
36
+ import type { TxThunk } from "@misofm/effect";
36
37
 
37
38
  import * as composition from "./contracts/musicos/composition.ts";
38
39
  import * as recording from "./contracts/musicos/recording.ts";
@@ -41,7 +42,7 @@ import { asU256, type UnsignedInput } from "./numeric.ts";
41
42
  import * as track from "./contracts/musicos/track.ts";
42
43
 
43
44
  /** A thunk that adds commands to a transaction. May be async (resolves at build time). */
44
- export type TxThunk = (tx: Transaction) => void | Promise<void>;
45
+ export type { TxThunk };
45
46
 
46
47
  // ============================================================================
47
48
  // Shared inputs
package/src/types.ts CHANGED
@@ -1,23 +1,30 @@
1
1
  // Copyright (c) Miso Labs, Inc.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ import { Schema } from "effect";
5
+
4
6
  // ============================================================================
5
7
  // Common
6
8
  // ============================================================================
7
9
 
8
10
  /** Basis points value (0-10000, where 10000 = 100%). */
9
- export interface BPS {
10
- value: number;
11
- }
11
+ export class BPS extends Schema.Class<BPS>("@misofm/musicos/BPS")({
12
+ value: Schema.Number,
13
+ }) {}
14
+
15
+ /** Shared lifecycle-state shape for Composition, Recording, and Release: Initialized -> Published(timestampMs). */
16
+ const WorkState = Schema.Union([
17
+ Schema.Struct({ type: Schema.Literal("Initialized") }),
18
+ Schema.Struct({ type: Schema.Literal("Published"), timestampMs: Schema.Number }),
19
+ ]);
12
20
 
13
21
  // ============================================================================
14
22
  // Composition
15
23
  // ============================================================================
16
24
 
17
25
  /** Lifecycle state of a composition. */
18
- export type CompositionState =
19
- | { type: "Initialized" }
20
- | { type: "Published"; timestampMs: number };
26
+ export const CompositionState = WorkState;
27
+ export type CompositionState = typeof WorkState.Type;
21
28
 
22
29
  /**
23
30
  * A musical composition representing the underlying written work.
@@ -28,19 +35,19 @@ export type CompositionState =
28
35
  *
29
36
  * State machine: Initialized -> Published (immutable after publish)
30
37
  */
31
- export interface Composition {
38
+ export class Composition extends Schema.Class<Composition>("@misofm/musicos/Composition")({
32
39
  /** Unique identifier for this composition. */
33
- id: string;
40
+ id: Schema.String,
34
41
  /** Current lifecycle state. */
35
- state: CompositionState;
42
+ state: CompositionState,
36
43
  /** Primary title of the composition. */
37
- title: string;
44
+ title: Schema.String,
38
45
  /**
39
46
  * Royalty rate this composition earns from each recording's revenue (basis
40
47
  * points, 0-10000). Immutable for the composition's lifetime.
41
48
  */
42
- royaltyRate: BPS;
43
- }
49
+ royaltyRate: BPS,
50
+ }) {}
44
51
 
45
52
  /**
46
53
  * Emitted once when a composition is published. A pure pointer carrying only the
@@ -57,21 +64,20 @@ export interface CompositionPublishedEvent {
57
64
  * The share type parameter T is extracted from the on-chain type
58
65
  * `CompositionAdminCap<T>` where T is the composition's share token type.
59
66
  */
60
- export interface CompositionAdminCap {
67
+ export class CompositionAdminCap extends Schema.Class<CompositionAdminCap>("@misofm/musicos/CompositionAdminCap")({
61
68
  /** The object ID of the admin cap. */
62
- id: string;
69
+ id: Schema.String,
63
70
  /** The share type parameter T from CompositionAdminCap<T>. */
64
- shareType: string;
65
- }
71
+ shareType: Schema.String,
72
+ }) {}
66
73
 
67
74
  // ============================================================================
68
75
  // Recording
69
76
  // ============================================================================
70
77
 
71
78
  /** Lifecycle state of a recording. */
72
- export type RecordingState =
73
- | { type: "Initialized" }
74
- | { type: "Published"; timestampMs: number };
79
+ export const RecordingState = WorkState;
80
+ export type RecordingState = typeof WorkState.Type;
75
81
 
76
82
  /**
77
83
  * An audio recording of a composition.
@@ -86,18 +92,18 @@ export type RecordingState =
86
92
  *
87
93
  * State machine: Initialized -> Published (immutable after publish)
88
94
  */
89
- export interface Recording {
95
+ export class Recording extends Schema.Class<Recording>("@misofm/musicos/Recording")({
90
96
  /** Unique identifier for this recording. */
91
- id: string;
97
+ id: Schema.String,
92
98
  /** Current lifecycle state. */
93
- state: RecordingState;
99
+ state: RecordingState,
94
100
  /**
95
101
  * Object ID of the parent composition. An identity/membership handle — not a
96
102
  * revenue routing target: the composition is paid via its recording-share
97
103
  * ownership, settled at recording creation. Immutable.
98
104
  */
99
- compositionId: string;
100
- }
105
+ compositionId: Schema.String,
106
+ }) {}
101
107
 
102
108
  /**
103
109
  * Emitted once when a recording is published. A pure pointer carrying only the
@@ -128,18 +134,19 @@ export interface CompositionSharesGrantedEvent {
128
134
  * The share type parameter T is extracted from the on-chain type
129
135
  * `RecordingAdminCap<T>` where T is the recording's share token type.
130
136
  */
131
- export interface RecordingAdminCap {
137
+ export class RecordingAdminCap extends Schema.Class<RecordingAdminCap>("@misofm/musicos/RecordingAdminCap")({
132
138
  /** The object ID of the admin cap. */
133
- id: string;
139
+ id: Schema.String,
134
140
  /** The share type parameter T from RecordingAdminCap<T>. */
135
- shareType: string;
136
- }
141
+ shareType: Schema.String,
142
+ }) {}
137
143
 
138
144
  // Track
139
145
  // ============================================================================
140
146
 
141
147
  /** Lifecycle state of a track on a release. */
142
- export type TrackState = "Unassigned" | "Assigned";
148
+ export const TrackState = Schema.Literals(["Unassigned", "Assigned"]);
149
+ export type TrackState = typeof TrackState.Type;
143
150
 
144
151
  /**
145
152
  * A track on a release, linking a recording to its position in the tracklist.
@@ -147,30 +154,29 @@ export type TrackState = "Unassigned" | "Assigned";
147
154
  * composition lineage, and — via the composition — the display title) is
148
155
  * reached.
149
156
  */
150
- export interface Track {
157
+ export class Track extends Schema.Class<Track>("@misofm/musicos/Track")({
151
158
  /** Current state of the track (Unassigned until the release claims it, then Assigned). */
152
- state: TrackState;
159
+ state: TrackState,
153
160
  /**
154
161
  * ID of the composition underlying this track's recording. An identity/
155
162
  * membership handle — not a revenue routing target: the composition is paid
156
163
  * via its recording-share ownership, and a track routes its full split to the
157
164
  * recording.
158
165
  */
159
- compositionId: string;
166
+ compositionId: Schema.String,
160
167
  /** ID of the recording on this track. */
161
- recordingId: string;
168
+ recordingId: Schema.String,
162
169
  /** Revenue split for this track within the release (in basis points). */
163
- splitBps: BPS;
164
- }
170
+ splitBps: BPS,
171
+ }) {}
165
172
 
166
173
  // ============================================================================
167
174
  // Release
168
175
  // ============================================================================
169
176
 
170
177
  /** Lifecycle state of a release. */
171
- export type ReleaseState =
172
- | { type: "Initialized" }
173
- | { type: "Published"; timestampMs: number };
178
+ export const ReleaseState = WorkState;
179
+ export type ReleaseState = typeof WorkState.Type;
174
180
 
175
181
  /**
176
182
  * A music release (album, EP, or single).
@@ -182,16 +188,16 @@ export type ReleaseState =
182
188
  *
183
189
  * State machine: Initialized -> Published (immutable after publish)
184
190
  */
185
- export interface Release {
191
+ export class Release extends Schema.Class<Release>("@misofm/musicos/Release")({
186
192
  /** Unique identifier for this release. */
187
- id: string;
193
+ id: Schema.String,
188
194
  /** Current lifecycle state. */
189
- state: ReleaseState;
195
+ state: ReleaseState,
190
196
  /** Title of the release. */
191
- title: string;
197
+ title: Schema.String,
192
198
  /** The ordered tracklist. */
193
- tracks: Track[];
194
- }
199
+ tracks: Schema.Array(Track),
200
+ }) {}
195
201
 
196
202
  /**
197
203
  * Emitted once when a release is published. A pure pointer carrying only the
@@ -208,15 +214,20 @@ export interface ReleaseRegistryCreatedEvent {
208
214
  createdBy: string;
209
215
  }
210
216
 
217
+ /** The shared canonical core `miso::release::ReleaseRegistry`. */
218
+ export class ReleaseRegistry extends Schema.Class<ReleaseRegistry>("@misofm/musicos/ReleaseRegistry")({
219
+ id: Schema.String,
220
+ }) {}
221
+
211
222
  /**
212
223
  * Admin cap for a Release, derived deterministically from the Release object ID.
213
224
  *
214
225
  * Unlike Composition and Recording admin caps, ReleaseAdminCap is not generic
215
226
  * (Release has no share type parameter) and stores a reference to its Release.
216
227
  */
217
- export interface ReleaseAdminCap {
228
+ export class ReleaseAdminCap extends Schema.Class<ReleaseAdminCap>("@misofm/musicos/ReleaseAdminCap")({
218
229
  /** The object ID of the admin cap. */
219
- id: string;
230
+ id: Schema.String,
220
231
  /** The object ID of the Release this cap administers. */
221
- releaseId: string;
222
- }
232
+ releaseId: Schema.String,
233
+ }) {}
package/src/view.ts CHANGED
@@ -6,9 +6,10 @@
6
6
  // changing state — used where the value is a pure function of inputs the chain
7
7
  // derives (e.g. the deterministic release id).
8
8
 
9
+ import { Effect } from "effect";
9
10
  import { Transaction } from "@mysten/sui/transactions";
10
11
  import { bcs } from "@mysten/sui/bcs";
11
- import type { ClientWithCoreApi } from "@mysten/sui/client";
12
+ import { SuiClient, SuiRpcError } from "@misofm/effect";
12
13
  import * as release from "./contracts/musicos/release.ts";
13
14
  import { asU256, asU64, type UnsignedInput } from "./numeric.ts";
14
15
 
@@ -31,13 +32,14 @@ export interface DeriveTargetReleaseIdParams {
31
32
  * Tracks embedded in a release must reference this exact ID, so it is computed
32
33
  * up front and threaded into the core release builder.
33
34
  */
34
- export async function deriveTargetReleaseId(
35
- client: ClientWithCoreApi,
35
+ export const deriveTargetReleaseId = Effect.fn("deriveTargetReleaseId")(function* (
36
36
  misoPackageId: string,
37
37
  params: DeriveTargetReleaseIdParams,
38
- ): Promise<string> {
38
+ ): Effect.fn.Return<string, SuiRpcError, SuiClient> {
39
39
  if (params.recordingIds.length !== params.splitBps.length) {
40
- throw new Error(`deriveTargetReleaseId: recordingIds (${params.recordingIds.length}) and splitBps (${params.splitBps.length}) length mismatch.`);
40
+ throw new Error(
41
+ `deriveTargetReleaseId: recordingIds (${params.recordingIds.length}) and splitBps (${params.splitBps.length}) length mismatch.`,
42
+ );
41
43
  }
42
44
 
43
45
  const tx = new Transaction();
@@ -54,12 +56,24 @@ export async function deriveTargetReleaseId(
54
56
  }),
55
57
  );
56
58
 
59
+ const client = yield* SuiClient;
57
60
  // gRPC/Core equivalent of devInspect: simulate with per-command return values.
58
- const res = await client.core.simulateTransaction({ transaction: tx, include: { commandResults: true } });
61
+ const res = yield* Effect.tryPromise({
62
+ try: (signal) => client.core.simulateTransaction({ transaction: tx, include: { commandResults: true }, signal }),
63
+ catch: (cause) => new SuiRpcError({ operation: "simulateTransaction", cause }),
64
+ });
59
65
  if (res.$kind !== "Transaction") {
60
- throw new Error(`derive_target_release_id simulation failed: ${JSON.stringify(res.FailedTransaction.status)}`);
66
+ return yield* new SuiRpcError({
67
+ operation: "simulateTransaction",
68
+ cause: new Error(`derive_target_release_id simulation failed: ${JSON.stringify(res.FailedTransaction.status)}`),
69
+ });
61
70
  }
62
71
  const returned = res.commandResults?.[0]?.returnValues?.[0]?.bcs;
63
- if (!returned) throw new Error("derive_target_release_id returned no value.");
72
+ if (!returned) {
73
+ return yield* new SuiRpcError({
74
+ operation: "simulateTransaction",
75
+ cause: new Error("derive_target_release_id returned no value."),
76
+ });
77
+ }
64
78
  return bcs.Address.parse(returned);
65
- }
79
+ });