@moises.ai/extension 0.0.19 → 1.0.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.
package/Readme.md CHANGED
@@ -1,34 +1 @@
1
- # Moises Extensions SDK
2
-
3
- ```jsx
4
- "use client"
5
-
6
- import { useEffect } from "react";
7
- import { initMoisesExtension, Button } from "@moises.ai/extension";
8
-
9
- const useMoisesExtension = initMoisesExtension({
10
- id: "your-extension-id",
11
- name: "Sample extension",
12
- description: "A bit about this extension",
13
- version: "1.0.0",
14
- author: "Moises Systems Incs",
15
- });
16
-
17
- export default function Home() {
18
- const { moises, ModalLayout, isConnected } = useMoisesExtension();
19
-
20
- useEffect(() => {
21
- if (!moises) {
22
- return
23
- }
24
-
25
- moises.link("footer:menu", { label: "Audio Editor" }, async () => {
26
- moises.ui.open({ mountPoint: "bottomPanel" });
27
- })
28
- }, [moises]);
29
-
30
- return (
31
- <Button onClick={() => moises.ui.alert({ title: "Hello", message: "World" })}>Click me</Button>
32
- );
33
- }
34
- ```
1
+ # Moises Extensions SDK
@@ -0,0 +1,108 @@
1
+ class h {
2
+ constructor({ target: e }) {
3
+ this.target = e, this.handlers = /* @__PURE__ */ new Map(), this.pendingRequests = /* @__PURE__ */ new Map(), this.requestId = 0, this.connected = !1, this.boundHandler = this.handleMessage.bind(this), this.connect();
4
+ }
5
+ connect() {
6
+ window.addEventListener("message", this.boundHandler), this.connected = !0;
7
+ }
8
+ disconnect() {
9
+ window.removeEventListener("message", this.boundHandler);
10
+ for (const [e, { reject: s }] of this.pendingRequests.entries())
11
+ s(new Error("Connection closed")), this.pendingRequests.delete(e);
12
+ this.connected = !1;
13
+ }
14
+ handleMessage(e) {
15
+ const { data: s, source: t, origin: n } = e;
16
+ if (t === this.target) {
17
+ if (s.type === "response") {
18
+ const { requestId: r, result: d, error: o } = s, c = this.pendingRequests.get(r);
19
+ c && (o ? c.reject(new Error(o)) : c.resolve(d), this.pendingRequests.delete(r));
20
+ return;
21
+ }
22
+ if (s.type === "request") {
23
+ const { method: r, params: d, requestId: o } = s, c = this.handlers.get(r);
24
+ if (!c) {
25
+ this.sendResponse(t, o, null, `No handler for method: ${r}`);
26
+ return;
27
+ }
28
+ Promise.resolve().then(() => c(d)).then((a) => this.sendResponse(t, o, a)).catch((a) => this.sendResponse(t, o, null, a.message));
29
+ }
30
+ }
31
+ }
32
+ sendResponse(e, s, t, n = null) {
33
+ e.postMessage({
34
+ type: "response",
35
+ requestId: s,
36
+ result: t,
37
+ error: n
38
+ }, "*");
39
+ }
40
+ on(e, s) {
41
+ this.handlers.set(e, s);
42
+ }
43
+ off(e) {
44
+ this.handlers.delete(e);
45
+ }
46
+ once(e, s) {
47
+ const t = async (n) => (this.off(e), s(n));
48
+ this.on(e, t);
49
+ }
50
+ async call(e, s) {
51
+ const t = this.requestId++;
52
+ return new Promise((n, r) => {
53
+ this.pendingRequests.set(t, { resolve: n, reject: r }), this.target.postMessage({
54
+ type: "request",
55
+ method: e,
56
+ params: s,
57
+ requestId: t
58
+ }, "*");
59
+ });
60
+ }
61
+ }
62
+ class u {
63
+ constructor(e) {
64
+ this.rpc = new h(e), this.proxy = this.createProxy();
65
+ }
66
+ createProxy() {
67
+ return new Proxy(this.rpc, {
68
+ get: (e, s) => s in e ? e[s] : new Proxy({}, {
69
+ get: (t, n) => async (r) => {
70
+ const d = `${s}.${n}`;
71
+ return e.call(d, r);
72
+ }
73
+ })
74
+ });
75
+ }
76
+ // Proxy the on method to maintain the same interface
77
+ // on(method, handler) {
78
+ // return this.rpc.on(method, handler);
79
+ // }
80
+ }
81
+ function l(i) {
82
+ const e = {
83
+ id: i.id,
84
+ name: i.name,
85
+ description: i.description,
86
+ icon: i.icon,
87
+ author: i.author,
88
+ version: i.version,
89
+ isLoaded: !1,
90
+ events: {}
91
+ }, { proxy: s, rpc: t } = new u({
92
+ target: window.parent
93
+ }), n = (
94
+ /** @type {any} */
95
+ s
96
+ );
97
+ return n.link = async (r, d, o) => {
98
+ const c = await n.register.link({ category: r, options: d });
99
+ t.on(`${c.id}`, o);
100
+ }, n.connect = async function() {
101
+ const r = n.register.extension(e);
102
+ return e.isLoaded = !0, r;
103
+ }, n.plugin = e, n;
104
+ }
105
+ export {
106
+ l as M,
107
+ h as R
108
+ };
package/dist/client.js ADDED
@@ -0,0 +1,4 @@
1
+ import { M as e } from "./client-Bt6Snfq-.js";
2
+ export {
3
+ e as MoisesExtension
4
+ };
@@ -0,0 +1,230 @@
1
+
2
+ /** Controlling common UI elements */
3
+ export interface UiApi {
4
+
5
+ /** Sets the extension size in the interface */
6
+ setPluginSize: (params: {
7
+
8
+ /** Width in pixels */
9
+ width: number;
10
+
11
+ /** Height in pixels */
12
+ height: number;
13
+ }) => void;
14
+
15
+ /** Displays a progress bar or loading indicator */
16
+ progress: (options: {
17
+
18
+ /** Progress message */
19
+ message?: string;
20
+
21
+ /** Progress value (0-100) */
22
+ value?: number;
23
+ }) => Promise<void>;
24
+
25
+ /** Displays an alert to the user */
26
+ alert: (options: {
27
+
28
+ /** Alert title */
29
+ title: string;
30
+
31
+ /** Alert message */
32
+ message: string;
33
+ }) => Promise<void>;
34
+
35
+ /** Displays a confirmation dialog */
36
+ confirm: (options: {
37
+
38
+ /** Confirmation title */
39
+ title: string;
40
+
41
+ /** Confirmation message */
42
+ message: string;
43
+ }) => Promise<boolean>;
44
+
45
+ /** Displays a text input dialog */
46
+ prompt: (options: {
47
+
48
+ /** Prompt title */
49
+ title: string;
50
+
51
+ /** Prompt message */
52
+ message: string;
53
+
54
+ /** Default input value */
55
+ defaultValue?: string;
56
+ }) => Promise<string>;
57
+
58
+ /** Creates a panel in the interface */
59
+ panel: (options: {
60
+
61
+ /** Panel title */
62
+ title: string;
63
+
64
+ /** Panel content */
65
+ content?: string;
66
+ }) => Promise<any>;
67
+
68
+ /** Closes the extension */
69
+ close: () => Promise<void>;
70
+
71
+ /** Opens the extension */
72
+ open: (params: {
73
+
74
+ /** Location where the extension will be mounted */
75
+ mountPoint: string;
76
+ }) => Promise<void>;
77
+ }
78
+
79
+
80
+ /** Session API for managing audio sessions, tracks, and playback controls */
81
+ export interface SessionApi {
82
+
83
+ /** Exports the audio from the current session */
84
+ export: () => Promise<any>;
85
+
86
+ /** Gets the list of tracks from the session */
87
+ tracks: () => Promise<any[]>;
88
+
89
+ /** Starts session playback */
90
+ play: () => void;
91
+
92
+ /** Pauses session playback */
93
+ pause: () => void;
94
+
95
+ /** Toggles between play and pause */
96
+ togglePlayback: () => void;
97
+
98
+ /** Clears the current selection in the session */
99
+ clearSelection: () => void;
100
+
101
+ /** Sets a selection in the session */
102
+ setSelection: (params: {
103
+
104
+ /** ID of the track to be selected */
105
+ trackId?: string;
106
+
107
+ /** Start position of the selection */
108
+ start: number;
109
+
110
+ /** End position of the selection */
111
+ end: number;
112
+ }) => void;
113
+ }
114
+
115
+
116
+ /** Track API for managing audio tracks */
117
+ export interface TrackApi {
118
+
119
+ /** Gets a track by its ID */
120
+ get: (trackId: string) => Promise<any>;
121
+
122
+ /** Creates a new track */
123
+ create: (params: {
124
+
125
+ /** The ID of the group to add the track to */
126
+ groupId: string;
127
+
128
+ /** The audio data for the track */
129
+ arrayBuffer: any;
130
+
131
+ /** The name of the track */
132
+ name?: string;
133
+
134
+ /** Additional options for the track */
135
+ options?: any;
136
+ }) => Promise<any>;
137
+
138
+ /** Updates a track */
139
+ update: (params: {
140
+
141
+ /** The ID of the track to update */
142
+ trackId: string;
143
+
144
+ /** The audio data for the track */
145
+ arrayBuffer: any;
146
+
147
+ /** Additional options for the track */
148
+ options?: any;
149
+ }) => Promise<any>;
150
+
151
+ /** Deletes a track */
152
+ delete: (trackId: string) => Promise<any>;
153
+ }
154
+
155
+
156
+ /** Registration methods for extensions */
157
+ export interface RegisterApi {
158
+
159
+ /** Register the extension with the parent application */
160
+ extension: (plugin: any) => any;
161
+
162
+ /** Register a link connection for data streaming */
163
+ link: (options: any) => any;
164
+ }
165
+
166
+
167
+ export interface MoisesAPI {
168
+ /** Controlling common UI elements */
169
+ ui: UiApi;
170
+ /** Session API for managing audio sessions, tracks, and playback controls */
171
+ session: SessionApi;
172
+ /** Track API for managing audio tracks */
173
+ track: TrackApi;
174
+ /** Registration methods for extensions */
175
+ register: RegisterApi;
176
+
177
+ /** Custom link method for easy connection setup (convenience wrapper around register.link) */
178
+ link: (category: string, options: any, cb: (data: any) => void) => Promise<void>;
179
+
180
+ /** Function to connect the extension to the parent application */
181
+ connect: () => Promise<any>;
182
+ /** Plugin metadata and configuration */
183
+ plugin: any;
184
+ }
185
+
186
+
187
+ export interface ExtensionInstance {
188
+ /** Function to connect the extension to the parent application */
189
+ connect: () => Promise<any>;
190
+ /** Plugin metadata and configuration */
191
+ plugin: any;
192
+ /** API to control Moises */
193
+ api: MoisesAPI;
194
+ }
195
+
196
+ export interface MoisesHook {
197
+ /** The complete Moises API with all functionality */
198
+ moises: MoisesAPI;
199
+ /** Plugin instance information */
200
+ plugin: any;
201
+ /** Connection status */
202
+ isConnected: boolean;
203
+ /** Modal layout component for plugin UI */
204
+ ModalLayout: (props: { children: any; width?: number; height?: number; }) => any;
205
+ }
206
+
207
+ export interface ExtensionOptions {
208
+ /** Unique identifier for the extension */
209
+ id: string;
210
+ /** Display name of the extension */
211
+ name: string;
212
+ /** Description of what the extension does */
213
+ description: string;
214
+ /** Icon to represent the extension */
215
+ icon: string;
216
+ /** Author of the extension */
217
+ author?: string;
218
+ /** Version number of the extension */
219
+ version?: string;
220
+ }
221
+
222
+ /**
223
+ * Creates a new Moises Extension instance (internal client)
224
+ */
225
+ export function MoisesExtension(options: ExtensionOptions): MoisesAPI;
226
+
227
+ /**
228
+ * Initializes a Moises extension hook for React components
229
+ */
230
+ export function initMoisesExtension(options: ExtensionOptions): () => MoisesHook;
package/dist/index.js CHANGED
@@ -1,175 +1,72 @@
1
- import { jsx as g } from "react/jsx-runtime";
2
- import { useState as q, useEffect as f } from "react";
3
- import { Box as p } from "@moises.ai/design-system";
4
- export * from "@moises.ai/design-system";
5
- class m {
6
- constructor({ target: e }) {
7
- this.target = e, this.handlers = /* @__PURE__ */ new Map(), this.pendingRequests = /* @__PURE__ */ new Map(), this.requestId = 0, this.connected = !1, this.boundHandler = this.handleMessage.bind(this), this.connect();
8
- }
9
- connect() {
10
- window.addEventListener("message", this.boundHandler), this.connected = !0;
11
- }
12
- disconnect() {
13
- window.removeEventListener("message", this.boundHandler);
14
- for (const [e, { reject: n }] of this.pendingRequests.entries())
15
- n(new Error("Connection closed")), this.pendingRequests.delete(e);
16
- this.connected = !1;
17
- }
18
- handleMessage(e) {
19
- const { data: n, source: s, origin: i } = e;
20
- if (s === this.target) {
21
- if (n.type === "response") {
22
- const { requestId: r, result: a, error: t } = n, c = this.pendingRequests.get(r);
23
- c && (t ? c.reject(new Error(t)) : c.resolve(a), this.pendingRequests.delete(r));
24
- return;
25
- }
26
- if (n.type === "request") {
27
- const { method: r, params: a, requestId: t } = n, c = this.handlers.get(r);
28
- if (!c) {
29
- this.sendResponse(s, t, null, `No handler for method: ${r}`);
30
- return;
31
- }
32
- Promise.resolve().then(() => c(a)).then((d) => this.sendResponse(s, t, d)).catch((d) => this.sendResponse(s, t, null, d.message));
33
- }
34
- }
35
- }
36
- sendResponse(e, n, s, i = null) {
37
- e.postMessage({
38
- type: "response",
39
- requestId: n,
40
- result: s,
41
- error: i
42
- }, "*");
43
- }
44
- on(e, n) {
45
- this.handlers.set(e, n);
46
- }
47
- off(e) {
48
- this.handlers.delete(e);
49
- }
50
- once(e, n) {
51
- const s = async (i) => (this.off(e), n(i));
52
- this.on(e, s);
53
- }
54
- async call(e, n) {
55
- const s = this.requestId++;
56
- return new Promise((i, r) => {
57
- this.pendingRequests.set(s, { resolve: i, reject: r }), this.target.postMessage({
58
- type: "request",
59
- method: e,
60
- params: n,
61
- requestId: s
62
- }, "*");
63
- });
64
- }
65
- }
66
- class v {
67
- constructor(e) {
68
- this.rpc = new m(e), this.proxy = this.createProxy();
69
- }
70
- createProxy() {
71
- return new Proxy(this.rpc, {
72
- get: (e, n) => n in e ? e[n] : new Proxy({}, {
73
- get: (s, i) => async (r) => {
74
- const a = `${n}.${i}`;
75
- return e.call(a, r);
76
- }
77
- })
78
- });
79
- }
80
- // Proxy the on method to maintain the same interface
81
- // on(method, handler) {
82
- // return this.rpc.on(method, handler);
83
- // }
84
- }
85
- function P(o) {
86
- const e = {
87
- id: o.id,
88
- name: o.name,
89
- description: o.description,
90
- icon: o.icon,
91
- author: o.author,
92
- version: o.version,
93
- isLoaded: !1,
94
- events: {}
95
- }, { proxy: n, rpc: s } = new v({
96
- target: window.parent
97
- });
98
- n.link = async (r, a, t) => {
99
- const c = await n.register.link({ category: r, options: a });
100
- s.on(`${c.id}`, t);
101
- };
102
- async function i() {
103
- const r = n.register.extension(e);
104
- return e.isLoaded = !0, r;
105
- }
106
- return { connect: i, plugin: e, api: n };
107
- }
108
- function E(o) {
109
- o.id;
110
- let e = null, n = !1;
111
- function s() {
112
- const [i, r] = q({
113
- plugin: e,
114
- isConnected: n,
115
- moises: e == null ? void 0 : e.api
1
+ import { jsx as m } from "react/jsx-runtime";
2
+ import { useState as x, useEffect as g } from "react";
3
+ import { M as y, R as M } from "./client-Bt6Snfq-.js";
4
+ function $(i) {
5
+ i.id;
6
+ let t = null, o = !1;
7
+ function r() {
8
+ const [c, u] = x({
9
+ plugin: null,
10
+ isConnected: o,
11
+ moises: null
116
12
  });
117
- f(() => {
118
- e || (e = P(o), r((t) => ({
119
- ...t,
120
- plugin: e,
121
- moises: e.api
13
+ g(() => {
14
+ t || (t = y(i), u((n) => ({
15
+ ...n,
16
+ plugin: t.plugin,
17
+ moises: t
18
+ // The entire pluginInstance IS the moises API
122
19
  })));
123
- }, [o]), f(() => {
124
- e && !n && e.connect().then(() => {
125
- n = !0, r((t) => ({
126
- ...t,
20
+ }, [i]), g(() => {
21
+ t && !o && t.connect().then(() => {
22
+ o = !0, u((n) => ({
23
+ ...n,
127
24
  isConnected: !0
128
25
  }));
129
26
  });
130
27
  }, []);
131
- function a({ children: t, width: c, height: d }) {
132
- const { moises: u } = i;
133
- return f(() => {
134
- u && u.ui.setPluginSize({ width: c, height: d });
135
- }, [c, d, u]), /* @__PURE__ */ g(p, { height: "100vh", style: { height: "100vh", backgroundColor: "var(--gray-1)" }, children: /* @__PURE__ */ g(p, { p: "4", children: t }) });
28
+ function d({ children: n, width: l, height: a }) {
29
+ const { moises: e } = c;
30
+ return g(() => {
31
+ e && e.ui.setPluginSize({ width: l, height: a });
32
+ }, [l, a, e]), /* @__PURE__ */ m("div", { height: "100vh", style: { height: "100vh", backgroundColor: "var(--gray-1)" }, children: /* @__PURE__ */ m("div", { p: "4", children: n }) });
136
33
  }
137
34
  return {
138
- ...i,
139
- ModalLayout: a
35
+ ...c,
36
+ ModalLayout: d
140
37
  };
141
38
  }
142
- return s;
39
+ return r;
143
40
  }
144
- function $({ id: o, url: e, exposedAPI: n, iframeRef: s, onRegisterMetadata: i, onRegisterLink: r }) {
145
- const a = {
146
- id: o,
147
- url: e
41
+ function j({ id: i, url: t, exposedAPI: o, iframeRef: r, onRegisterMetadata: c, onRegisterLink: u }) {
42
+ const d = {
43
+ id: i,
44
+ url: t
148
45
  };
149
- s.current && (s.current.src = e);
150
- const t = new m({
151
- target: s.current.contentWindow
46
+ r.current && (r.current.src = t);
47
+ const n = new M({
48
+ target: r.current.contentWindow
152
49
  });
153
- t.on("register.extension", async (u) => {
154
- i(u);
155
- }), t.on("register.link", async ({ category: u, options: l }) => {
156
- const h = `link:${u}:${l.label}`;
157
- return r({ id: h, category: u, options: l }), { id: h };
50
+ n.on("register.extension", async (e) => {
51
+ c(e);
52
+ }), n.on("register.link", async ({ category: e, options: s }) => {
53
+ const f = `link:${e}:${s.label}`;
54
+ return u({ id: f, category: e, options: s }), { id: f };
158
55
  });
159
- for (const [u, l] of Object.entries(n))
160
- for (const [h, y] of Object.entries(l)) {
161
- const w = `${u}.${h}`;
162
- t.on(w, async (x) => await y(x));
56
+ for (const [e, s] of Object.entries(o))
57
+ for (const [f, p] of Object.entries(s)) {
58
+ const h = `${e}.${f}`;
59
+ n.on(h, async (v) => await p(v));
163
60
  }
164
- function c(u, l) {
165
- return t.call(u, l);
61
+ function l(e, s) {
62
+ return n.call(e, s);
166
63
  }
167
- function d() {
168
- t.disconnect();
64
+ function a() {
65
+ n.disconnect();
169
66
  }
170
- return { plugin: a, rpc: t, call: c, disconnect: d };
67
+ return { plugin: d, rpc: n, call: l, disconnect: a };
171
68
  }
172
69
  export {
173
- $ as MoisesExtensionHost,
174
- E as initMoisesExtension
70
+ j as MoisesExtensionHost,
71
+ $ as initMoisesExtension
175
72
  };
package/package.json CHANGED
@@ -1,37 +1,35 @@
1
1
  {
2
2
  "name": "@moises.ai/extension",
3
- "version": "0.0.19",
3
+ "version": "1.0.0",
4
4
  "description": "SDK for Moises AI extensions",
5
5
  "private": false,
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
8
8
  "module": "./dist/index.js",
9
- "style": "styles.css",
10
9
  "exports": {
11
10
  ".": {
12
11
  "import": "./dist/index.js",
13
- "require": "./dist/index.js"
12
+ "require": "./dist/index.js",
13
+ "types": "./dist/index.d.ts"
14
14
  },
15
- "./icons": {
16
- "import": "./dist/icons.js",
17
- "require": "./dist/icons.js"
18
- },
19
- "./primitives": {
20
- "import": "./dist/primitives.js",
21
- "require": "./dist/primitives.js"
15
+ "./client": {
16
+ "import": "./dist/client.js",
17
+ "require": "./dist/client.js",
18
+ "types": "./src/client.d.ts"
22
19
  },
23
20
  "./styles.css": "./styles.css"
24
21
  },
25
22
  "files": [
26
23
  "dist",
27
- "styles.css"
24
+ "styles.css",
25
+ "src/client.d.ts",
26
+ "src/index.d.ts"
28
27
  ],
29
28
  "scripts": {
30
29
  "build": "vite build",
31
- "dev": "vite build --watch"
32
- },
33
- "dependencies": {
34
- "@moises.ai/design-system": "2.0.15"
30
+ "dev": "vite build --watch",
31
+ "generate-types": "node scripts/generate-types.js",
32
+ "generate-typed-client": "node scripts/generate-typed-client.js"
35
33
  },
36
34
  "peerDependencies": {
37
35
  "react": "*",