@moises.ai/extension 0.0.20 → 1.0.1

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/dist/index.js CHANGED
@@ -1,389 +1,72 @@
1
- import { jsx as f } from "react/jsx-runtime";
2
- import { useState as q, useEffect as h } from "react";
3
- import { Box as p } from "@moises.ai/design-system";
4
- export * from "@moises.ai/design-system";
5
- class y {
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: o, origin: i } = e;
20
- if (o === this.target) {
21
- if (n.type === "response") {
22
- const { requestId: r, result: l, error: t } = n, c = this.pendingRequests.get(r);
23
- c && (t ? c.reject(new Error(t)) : c.resolve(l), this.pendingRequests.delete(r));
24
- return;
25
- }
26
- if (n.type === "request") {
27
- const { method: r, params: l, requestId: t } = n, c = this.handlers.get(r);
28
- if (!c) {
29
- this.sendResponse(o, t, null, `No handler for method: ${r}`);
30
- return;
31
- }
32
- Promise.resolve().then(() => c(l)).then((a) => this.sendResponse(o, t, a)).catch((a) => this.sendResponse(o, t, null, a.message));
33
- }
34
- }
35
- }
36
- sendResponse(e, n, o, i = null) {
37
- e.postMessage({
38
- type: "response",
39
- requestId: n,
40
- result: o,
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 o = async (i) => (this.off(e), n(i));
52
- this.on(e, o);
53
- }
54
- async call(e, n) {
55
- const o = this.requestId++;
56
- return new Promise((i, r) => {
57
- this.pendingRequests.set(o, { resolve: i, reject: r }), this.target.postMessage({
58
- type: "request",
59
- method: e,
60
- params: n,
61
- requestId: o
62
- }, "*");
63
- });
64
- }
65
- }
66
- class P {
67
- constructor(e) {
68
- this.rpc = new y(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: (o, i) => async (r) => {
74
- const l = `${n}.${i}`;
75
- return e.call(l, 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
- const v = {
86
- /**
87
- * Exports the audio from the current session
88
- * @async
89
- * @function export
90
- * @memberof session
91
- * @returns {Promise<AudioData>} Promise that resolves with the exported audio data
92
- * @example const audioData = await session.export()
93
- */
94
- export: async function() {
95
- return console.log("session.export");
96
- },
97
- /**
98
- * Gets the list of tracks from the session
99
- * @async
100
- * @function tracks
101
- * @memberof session
102
- * @returns {Promise<Array>} Promise that resolves with an array of tracks
103
- * @example
104
- * const tracks = await session.tracks()
105
- * console.log(tracks.length) // number of tracks
106
- */
107
- tracks: async function() {
108
- return console.log("session.tracks");
109
- },
110
- /**
111
- * Starts session playback
112
- * @function play
113
- * @memberof session
114
- * @returns {void} Does not return a value
115
- * @example session.play()
116
- */
117
- play: function() {
118
- return console.log("session.play");
119
- },
120
- /**
121
- * Pauses session playback
122
- * @function pause
123
- * @memberof session
124
- * @returns {void} Does not return a value
125
- * @example session.pause()
126
- */
127
- pause: function() {
128
- return console.log("session.pause");
129
- },
130
- /**
131
- * Toggles between play and pause
132
- * @function togglePlayback
133
- * @memberof session
134
- * @returns {void} Does not return a value
135
- * @example session.togglePlayback()
136
- */
137
- togglePlayback: function() {
138
- return console.log("session.togglePlayback");
139
- },
140
- /**
141
- * Clears the current selection in the session
142
- * @function clearSelection
143
- * @memberof session
144
- * @returns {void} Does not return a value
145
- * @example session.clearSelection()
146
- */
147
- clearSelection: function() {
148
- return console.log("session.clearSelection");
149
- },
150
- /**
151
- * Sets a selection in the session
152
- * @function setSelection
153
- * @memberof session
154
- * @param {Object} params - Selection parameters
155
- * @param {string} params.trackId - ID of the track to be selected
156
- * @param {number} params.start - Start position of the selection
157
- * @param {number} params.end - End position of the selection
158
- * @returns {void} Does not return a value
159
- * @example
160
- * // Selects an interval in a specific track
161
- * session.setSelection({
162
- * trackId: "track-123",
163
- * start: 0,
164
- * end: 30
165
- * })
166
- *
167
- * // Selects an interval without specifying a track
168
- * session.setSelection({ start: 10, end: 20 })
169
- */
170
- setSelection: function(s) {
171
- return console.log("session.setSelection", s);
172
- }
173
- }, R = {
174
- /**
175
- * Sets the extension size in the interface
176
- * @function setPluginSize
177
- * @memberof ui
178
- * @param {Object} params - Size parameters
179
- * @param {number} params.width - Width in pixels
180
- * @param {number} params.height - Height in pixels
181
- * @returns {void} Does not return a value
182
- * @example ui.setPluginSize({ width: 800, height: 600 })
183
- */
184
- setPluginSize: function(s) {
185
- return console.log("ui.setPluginSize", s);
186
- },
187
- /**
188
- * Displays a progress bar or loading indicator
189
- * @async
190
- * @function progress
191
- * @memberof ui
192
- * @param {Object} options - Progress configuration options
193
- * @param {string} options.message - Progress message
194
- * @param {number} options.value - Progress value (0-100)
195
- * @returns {Promise<void>} Promise that resolves when the operation is complete
196
- * @example await ui.progress({ message: "Loading...", value: 50 })
197
- */
198
- progress: async function(s) {
199
- return console.log("ui.progress", s);
200
- },
201
- /**
202
- * Displays an alert to the user
203
- * @async
204
- * @function alert
205
- * @memberof ui
206
- * @param {Object} options - Alert configuration options
207
- * @param {string} options.title - Alert title
208
- * @param {string} options.message - Alert message
209
- * @returns {Promise<void>} Promise that resolves when the alert is closed
210
- * @example await ui.alert({ title: "Notice", message: "Operation completed!" })
211
- */
212
- alert: async function(s) {
213
- return console.log("ui.alert", s);
214
- },
215
- /**
216
- * Displays a confirmation dialog
217
- * @async
218
- * @function confirm
219
- * @memberof ui
220
- * @param {Object} options - Confirmation configuration options
221
- * @param {string} options.title - Confirmation title
222
- * @param {string} options.message - Confirmation message
223
- * @returns {Promise<boolean>} Promise that resolves with true if confirmed, false if cancelled
224
- * @example
225
- * const confirmed = await ui.confirm({
226
- * title: "Confirm",
227
- * message: "Do you want to continue?"
228
- * })
229
- */
230
- confirm: async function(s) {
231
- return console.log("ui.confirm", s);
232
- },
233
- /**
234
- * Displays a text input dialog
235
- * @async
236
- * @function prompt
237
- * @memberof ui
238
- * @param {Object} options - Prompt configuration options
239
- * @param {string} options.title - Prompt title
240
- * @param {string} options.message - Prompt message
241
- * @param {string} options.defaultValue - Default input value
242
- * @returns {Promise<string>} Promise that resolves with the entered text
243
- * @example
244
- * const userInput = await ui.prompt({
245
- * title: "Name",
246
- * message: "Enter your name:"
247
- * })
248
- */
249
- prompt: async function(s) {
250
- return console.log("ui.prompt", s);
251
- },
252
- /**
253
- * Creates a panel in the interface
254
- * @async
255
- * @function panel
256
- * @memberof ui
257
- * @param {Object} options - Panel configuration options
258
- * @param {string} options.title - Panel title
259
- * @param {string} options.content - Panel content
260
- * @returns {Promise<Object>} Promise that resolves with the created panel object
261
- * @returns {string} returns.id - Unique panel ID
262
- * @example
263
- * const panel = await ui.panel({ title: "My Panel" })
264
- * console.log(panel.id) // "panel-1"
265
- */
266
- panel: async function(s) {
267
- return console.log("ui.panel", s);
268
- },
269
- /**
270
- * Closes the extension
271
- * @async
272
- * @function close
273
- * @memberof ui
274
- * @returns {Promise<void>} Promise that resolves when the extension is closed
275
- * @example await ui.close()
276
- */
277
- close: async function() {
278
- return console.log("ui.close");
279
- },
280
- /**
281
- * Opens the extension
282
- * @async
283
- * @function open
284
- * @memberof ui
285
- * @param {Object} [params]={} - Open parameters
286
- * @param {string} params.mountPoint="sidePanel" - Location where the extension will be mounted
287
- * @returns {Promise<void>} Promise that resolves when the extension is opened
288
- * @example
289
- * // Opens in side panel (default)
290
- * await ui.open()
291
- *
292
- * // Opens in a specific location
293
- * await ui.open({ mountPoint: "mainPanel" })
294
- */
295
- open: async function(s = {}) {
296
- return console.log("ui.open", s);
297
- }
298
- };
299
- function b(s) {
300
- const e = {
301
- id: s.id,
302
- name: s.name,
303
- description: s.description,
304
- icon: s.icon,
305
- author: s.author,
306
- version: s.version,
307
- isLoaded: !1,
308
- events: {}
309
- }, { proxy: n, rpc: o } = new P({
310
- target: window.parent
311
- });
312
- n.link = async (r, l, t) => {
313
- const c = await n.register.link({ category: r, options: l });
314
- o.on(`${c.id}`, t);
315
- }, n.ui = R, n.session = v;
316
- async function i() {
317
- const r = n.register.extension(e);
318
- return e.isLoaded = !0, r;
319
- }
320
- return { connect: i, plugin: e, api: n };
321
- }
322
- function E(s) {
323
- s.id;
324
- let e = null, n = !1;
325
- function o() {
326
- const [i, r] = q({
327
- plugin: e,
328
- isConnected: n,
329
- 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
330
12
  });
331
- h(() => {
332
- e || (e = b(s), r((t) => ({
333
- ...t,
334
- plugin: e,
335
- 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
336
19
  })));
337
- }, [s]), h(() => {
338
- e && !n && e.connect().then(() => {
339
- n = !0, r((t) => ({
340
- ...t,
20
+ }, [i]), g(() => {
21
+ t && !o && t.connect().then(() => {
22
+ o = !0, u((n) => ({
23
+ ...n,
341
24
  isConnected: !0
342
25
  }));
343
26
  });
344
27
  }, []);
345
- function l({ children: t, width: c, height: a }) {
346
- const { moises: u } = i;
347
- return h(() => {
348
- u && u.ui.setPluginSize({ width: c, height: a });
349
- }, [c, a, u]), /* @__PURE__ */ f(p, { height: "100vh", style: { height: "100vh", backgroundColor: "var(--gray-1)" }, children: /* @__PURE__ */ f(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 }) });
350
33
  }
351
34
  return {
352
- ...i,
353
- ModalLayout: l
35
+ ...c,
36
+ ModalLayout: d
354
37
  };
355
38
  }
356
- return o;
39
+ return r;
357
40
  }
358
- function $({ id: s, url: e, exposedAPI: n, iframeRef: o, onRegisterMetadata: i, onRegisterLink: r }) {
359
- const l = {
360
- id: s,
361
- 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
362
45
  };
363
- o.current && (o.current.src = e);
364
- const t = new y({
365
- target: o.current.contentWindow
46
+ r.current && (r.current.src = t);
47
+ const n = new M({
48
+ target: r.current.contentWindow
366
49
  });
367
- t.on("register.extension", async (u) => {
368
- i(u);
369
- }), t.on("register.link", async ({ category: u, options: d }) => {
370
- const g = `link:${u}:${d.label}`;
371
- return r({ id: g, category: u, options: d }), { id: g };
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 };
372
55
  });
373
- for (const [u, d] of Object.entries(n))
374
- for (const [g, m] of Object.entries(d)) {
375
- const w = `${u}.${g}`;
376
- t.on(w, async (x) => await m(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));
377
60
  }
378
- function c(u, d) {
379
- return t.call(u, d);
61
+ function l(e, s) {
62
+ return n.call(e, s);
380
63
  }
381
64
  function a() {
382
- t.disconnect();
65
+ n.disconnect();
383
66
  }
384
- return { plugin: l, rpc: t, call: c, disconnect: a };
67
+ return { plugin: d, rpc: n, call: l, disconnect: a };
385
68
  }
386
69
  export {
387
- $ as MoisesExtensionHost,
388
- E as initMoisesExtension
70
+ j as MoisesExtensionHost,
71
+ $ as initMoisesExtension
389
72
  };
package/package.json CHANGED
@@ -1,37 +1,39 @@
1
1
  {
2
2
  "name": "@moises.ai/extension",
3
- "version": "0.0.20",
3
+ "version": "1.0.1",
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",
9
+ "bin": {
10
+ "moises-extension": "./scripts/init-boilerplate.js"
11
+ },
10
12
  "exports": {
11
13
  ".": {
12
14
  "import": "./dist/index.js",
13
- "require": "./dist/index.js"
14
- },
15
- "./icons": {
16
- "import": "./dist/icons.js",
17
- "require": "./dist/icons.js"
15
+ "require": "./dist/index.js",
16
+ "types": "./dist/index.d.ts"
18
17
  },
19
- "./primitives": {
20
- "import": "./dist/primitives.js",
21
- "require": "./dist/primitives.js"
18
+ "./client": {
19
+ "import": "./dist/client.js",
20
+ "require": "./dist/client.js",
21
+ "types": "./src/client.d.ts"
22
22
  },
23
23
  "./styles.css": "./styles.css"
24
24
  },
25
25
  "files": [
26
26
  "dist",
27
- "styles.css"
27
+ "styles.css",
28
+ "src/client.d.ts",
29
+ "src/index.d.ts",
30
+ "scripts/init-boilerplate.js"
28
31
  ],
29
32
  "scripts": {
30
33
  "build": "vite build",
31
- "dev": "vite build --watch"
32
- },
33
- "dependencies": {
34
- "@moises.ai/design-system": "2.0.15"
34
+ "dev": "vite build --watch",
35
+ "generate-types": "node scripts/generate-types.js",
36
+ "generate-typed-client": "node scripts/generate-typed-client.js"
35
37
  },
36
38
  "peerDependencies": {
37
39
  "react": "*",
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env node
2
+ import { promisify } from "util";
3
+ import cp from "child_process";
4
+ import path from "path";
5
+ import fs from "fs";
6
+
7
+ // convert libs to promises
8
+ const exec = promisify(cp.exec);
9
+ const rm = promisify(fs.rm);
10
+
11
+ // Simple custom spinner implementation
12
+ class Spinner {
13
+ constructor(message) {
14
+ this.message = message;
15
+ this.frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
16
+ this.currentFrame = 0;
17
+ this.isSpinning = false;
18
+ this.interval = null;
19
+ }
20
+
21
+ start() {
22
+ this.isSpinning = true;
23
+ process.stdout.write('\x1B[?25l'); // Hide cursor
24
+ this.interval = setInterval(() => {
25
+ process.stdout.write('\r' + this.frames[this.currentFrame] + ' ' + this.message);
26
+ this.currentFrame = (this.currentFrame + 1) % this.frames.length;
27
+ }, 100);
28
+ return this;
29
+ }
30
+
31
+ succeed(successMessage) {
32
+ this.stop();
33
+ process.stdout.write('\r✅ ' + (successMessage || this.message) + '\n');
34
+ }
35
+
36
+ fail(errorMessage) {
37
+ this.stop();
38
+ process.stdout.write('\r❌ ' + (errorMessage || this.message) + '\n');
39
+ }
40
+
41
+ stop() {
42
+ if (this.interval) {
43
+ clearInterval(this.interval);
44
+ this.interval = null;
45
+ }
46
+ this.isSpinning = false;
47
+ process.stdout.write('\x1B[?25h'); // Show cursor
48
+ process.stdout.write('\r' + ' '.repeat(this.message.length + 10) + '\r');
49
+ }
50
+ }
51
+
52
+ if (process.argv.length < 3) {
53
+ console.log("You have to provide a name for your extension project.");
54
+ console.log("For example:");
55
+ console.log(" npx @moises.ai/extension my-extension");
56
+ process.exit(1);
57
+ }
58
+
59
+ // Display ASCII banner
60
+ console.log(`
61
+ _ _
62
+ (_) (_)
63
+ _ __ ___ ___ _ ___ ___ ___ __ _ _
64
+ | '_ \` _ \\ / _ \\| / __|/ _ \\/ __| / _\` | |
65
+ | | | | | | (_) | \\__ \\ __/\\__ \\| (_| | |
66
+ |_| |_| |_|\\___/|_|___/\\___||___(_)__,_|_|
67
+
68
+ `);
69
+
70
+ const projectName = process.argv[2];
71
+ const currentPath = process.cwd();
72
+ const projectPath = path.join(currentPath, projectName);
73
+ const git_repo = "https://github.com/moises-ai/extensions-boilerplate.git";
74
+
75
+ // create project directory
76
+ if (fs.existsSync(projectPath)) {
77
+ console.log(`The directory ${projectName} already exists in the current directory, please give it another name.`);
78
+ process.exit(1);
79
+ } else {
80
+ fs.mkdirSync(projectPath);
81
+ }
82
+
83
+ try {
84
+ const gitSpinner = new Spinner("Downloading boilerplate files...").start();
85
+ // clone the repo into the project folder -> creates the new boilerplate
86
+ await exec(`git clone --depth 1 ${git_repo} ${projectPath} --quiet`);
87
+ gitSpinner.succeed();
88
+
89
+ const cleanSpinner = new Spinner("Cleaning up template files...").start();
90
+ // remove git history to start fresh
91
+ const rmGit = rm(path.join(projectPath, ".git"), { recursive: true, force: true });
92
+ await rmGit;
93
+ cleanSpinner.succeed();
94
+
95
+ // change to project directory for npm operations
96
+ process.chdir(projectPath);
97
+
98
+ const npmSpinner = new Spinner("Installing dependencies...").start();
99
+ await exec("npm install");
100
+ npmSpinner.succeed();
101
+
102
+ console.log("\n🎉 Extension project created successfully!");
103
+ console.log("\nNext steps:");
104
+ console.log(` cd ${projectName}`);
105
+ console.log(` npm run dev`);
106
+ console.log("\nHappy coding! 🚀");
107
+
108
+ } catch (error) {
109
+ // clean up in case of error, so the user does not have to do it manually
110
+ fs.rmSync(projectPath, { recursive: true, force: true });
111
+ console.error("❌ Error creating extension project:");
112
+ console.error(error.message);
113
+ process.exit(1);
114
+ }