ableton-js 2.1.8 → 2.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.
package/CHANGELOG.md CHANGED
@@ -4,8 +4,31 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ #### [v2.3.0](https://github.com/leolabs/ableton.js/compare/v2.2.1-0...v2.3.0)
8
+
9
+ - :sparkles: Add the clip's name as an observable property [`78c9969`](https://github.com/leolabs/ableton.js/commit/78c99694e8e230ad4ecb022316ebed731994fc6f)
10
+
11
+ #### [v2.2.1-0](https://github.com/leolabs/ableton.js/compare/v2.2.0...v2.2.1-0)
12
+
13
+ > 26 March 2022
14
+
15
+ - :sparkles: Implement basic Application interface to fetch live version and dialog information [`5aba86f`](https://github.com/leolabs/ableton.js/commit/5aba86f811ff36d43a99a657a2789e3d9ac59cce)
16
+ - :white_check_mark: Add tests for the application namespace [`9954cdf`](https://github.com/leolabs/ableton.js/commit/9954cdf724a41d8705a62fa50ac5cb06b162e1f1)
17
+ - :sparkles: Add support for listing clips in arrangement view [`e7df690`](https://github.com/leolabs/ableton.js/commit/e7df69060ccc7e098b1b4f5d418a79a60d57c4ce)
18
+
19
+ #### [v2.2.0](https://github.com/leolabs/ableton.js/compare/v2.1.8...v2.2.0)
20
+
21
+ > 18 March 2022
22
+
23
+ - :memo: Fix details in readme [`#36`](https://github.com/leolabs/ableton.js/pull/36)
24
+ - :bug: Fix errors on quick disconnect/connect [`#42`](https://github.com/leolabs/ableton.js/pull/42)
25
+ - :bug: Fix connected status on load of Ableton class [`#40`](https://github.com/leolabs/ableton.js/pull/40)
26
+ - :wrench: Add GitHub repo to NPM page [`#39`](https://github.com/leolabs/ableton.js/pull/39)
27
+
7
28
  #### [v2.1.8](https://github.com/leolabs/ableton.js/compare/v2.1.7...v2.1.8)
8
29
 
30
+ > 18 February 2022
31
+
9
32
  - :sparkles: Add observable props for quantization [`ffd192d`](https://github.com/leolabs/ableton.js/commit/ffd192d1590f33cdd18c2e01dbf66a0bc67878e4)
10
33
 
11
34
  #### [v2.1.7](https://github.com/leolabs/ableton.js/compare/v2.1.6...v2.1.7)
package/README.md CHANGED
@@ -22,8 +22,7 @@ get an overview of the current of your set.
22
22
 
23
23
  To use this library, you'll need to install and activate the MIDI Remote Script
24
24
  in Ableton.js. To do that, copy the `midi-script` folder of this repo to
25
- Ableton's Remote Scripts folder. If you prefer, you can rename it to something
26
- like `AbletonJS` for better identification. The MIDI Remote Scripts folder is
25
+ Ableton's Remote Scripts folder and rename it to `AbletonJS`. The MIDI Remote Scripts folder is
27
26
  usually located at:
28
27
 
29
28
  - **Windows:** {path to Ableton}\Resources\MIDI\Remote Scripts
@@ -55,8 +54,8 @@ const test = async () => {
55
54
  ableton.song.addListener("is_playing", (p) => console.log("Playing:", p));
56
55
  ableton.song.addListener("tempo", (t) => console.log("Tempo:", t));
57
56
 
58
- const cues = await ableton.get("cue_points");
59
- console.log(cues.map((c) => c.raw));
57
+ const tempo = await ableton.song.get("tempo");
58
+ console.log(tempo);
60
59
  };
61
60
 
62
61
  test();
package/index.d.ts CHANGED
@@ -2,6 +2,7 @@
2
2
  import { EventEmitter } from "events";
3
3
  import { Song } from "./ns/song";
4
4
  import { Internal } from "./ns/internal";
5
+ import { Application } from "./ns/application";
5
6
  interface Command {
6
7
  uuid: string;
7
8
  ns: string;
@@ -42,6 +43,7 @@ export declare class Ableton extends EventEmitter implements ConnectionEventEmit
42
43
  private buffer;
43
44
  private latency;
44
45
  song: Song;
46
+ application: Application;
45
47
  internal: Internal;
46
48
  constructor(host?: string, sendPort?: number, listenPort?: number, heartbeatInterval?: number);
47
49
  close(): void;
package/index.js CHANGED
@@ -67,6 +67,7 @@ var semver_1 = __importDefault(require("semver"));
67
67
  var zlib_1 = require("zlib");
68
68
  var song_1 = require("./ns/song");
69
69
  var internal_1 = require("./ns/internal");
70
+ var application_1 = require("./ns/application");
70
71
  var package_version_1 = require("./util/package-version");
71
72
  var TimeoutError = /** @class */ (function (_super) {
72
73
  __extends(TimeoutError, _super);
@@ -92,11 +93,12 @@ var Ableton = /** @class */ (function (_super) {
92
93
  _this.listenPort = listenPort;
93
94
  _this.msgMap = new Map();
94
95
  _this.eventListeners = new Map();
95
- _this._isConnected = true;
96
+ _this._isConnected = false;
96
97
  _this.cancelConnectionEvent = false;
97
98
  _this.buffer = [];
98
99
  _this.latency = 0;
99
100
  _this.song = new song_1.Song(_this);
101
+ _this.application = new application_1.Application(_this);
100
102
  _this.internal = new internal_1.Internal(_this);
101
103
  _this.client = dgram_1.default.createSocket({ type: "udp4", reuseAddr: true });
102
104
  _this.client.bind(_this.listenPort, host);
@@ -123,6 +125,7 @@ var Ableton = /** @class */ (function (_super) {
123
125
  if (this._isConnected && !this.cancelConnectionEvent) {
124
126
  this._isConnected = false;
125
127
  this.eventListeners.clear();
128
+ this.msgMap.forEach(function (msg) { return msg.clearTimeout(); });
126
129
  this.msgMap.clear();
127
130
  this.emit("disconnect", "heartbeat");
128
131
  }
@@ -188,8 +191,9 @@ var Ableton = /** @class */ (function (_super) {
188
191
  return functionCallback.rej(new Error(data.data));
189
192
  }
190
193
  if (data.event === "disconnect") {
191
- this.msgMap.clear();
192
194
  this.eventListeners.clear();
195
+ this.msgMap.forEach(function (msg) { return msg.clearTimeout(); });
196
+ this.msgMap.clear();
193
197
  if (this._isConnected === true) {
194
198
  this._isConnected = false;
195
199
  this.cancelConnectionEvent = true;
@@ -236,7 +240,7 @@ var Ableton = /** @class */ (function (_super) {
236
240
  rej(new TimeoutError([
237
241
  "The command " + cls + "." + name + "(" + arg + ") timed out after " + timeout + " ms.",
238
242
  "Please make sure that Ableton is running and that you have the latest",
239
- "version of AbletonJS' midi script installed, listening on port",
243
+ "version of AbletonJS' midi script installed and renamed to \"AbletonJS\", listening on port",
240
244
  _this.sendPort + " and sending on port " + _this.listenPort + ".",
241
245
  ].join(" "), payload));
242
246
  }, timeout);
@@ -248,6 +252,9 @@ var Ableton = /** @class */ (function (_super) {
248
252
  res(data);
249
253
  },
250
254
  rej: rej,
255
+ clearTimeout: function () {
256
+ clearTimeout(timeoutId);
257
+ },
251
258
  });
252
259
  _this.sendRaw(msg);
253
260
  })];
@@ -3,6 +3,7 @@ import sys
3
3
 
4
4
  from .Socket import Socket
5
5
  from .Interface import Interface
6
+ from .Application import Application
6
7
  from .CuePoint import CuePoint
7
8
  from .Device import Device
8
9
  from .DeviceParameter import DeviceParameter
@@ -14,6 +15,7 @@ from .Internal import Internal
14
15
  from .ClipSlot import ClipSlot
15
16
  from .Clip import Clip
16
17
  from _Framework.ControlSurface import ControlSurface
18
+ from Live.Base import Timer
17
19
 
18
20
 
19
21
  class AbletonJS(ControlSurface):
@@ -25,6 +27,7 @@ class AbletonJS(ControlSurface):
25
27
  self.socket = Socket(self.command_handler)
26
28
 
27
29
  self.handlers = {
30
+ "application": Application(c_instance, self.socket, self.application()),
28
31
  "internal": Internal(c_instance, self.socket),
29
32
  "cue-point": CuePoint(c_instance, self.socket),
30
33
  "device": Device(c_instance, self.socket),
@@ -37,21 +40,21 @@ class AbletonJS(ControlSurface):
37
40
  "clip": Clip(c_instance, self.socket)
38
41
  }
39
42
 
40
- self.parse()
43
+ self.recv_loop = Timer(
44
+ callback=self.socket.process, interval=10, repeat=True)
45
+
46
+ self.recv_loop.start()
41
47
 
42
48
  self.socket.send("connect")
43
49
 
44
50
  def disconnect(self):
45
51
  self.log_message("Disconnecting")
52
+ self.recv_loop.stop()
46
53
  self.socket.send("disconnect")
47
54
  self.socket.shutdown()
48
55
  Interface.listeners.clear()
49
56
  super(AbletonJS, self).disconnect()
50
57
 
51
- def parse(self):
52
- self.socket.process()
53
- self.schedule_message(1, self.parse)
54
-
55
58
  def command_handler(self, payload):
56
59
  self.log_message("Received command: " + str(payload))
57
60
  namespace = payload["ns"]
@@ -0,0 +1,26 @@
1
+ from __future__ import absolute_import
2
+ from .Interface import Interface
3
+
4
+ import Live
5
+
6
+
7
+ class Application(Interface):
8
+ def __init__(self, c_instance, socket, application):
9
+ super(Application, self).__init__(c_instance, socket)
10
+ self.application = application
11
+ self.log_message("Version: " + self.get_version(self.get_ns()))
12
+
13
+ def get_ns(self, nsid=None):
14
+ return self.application
15
+
16
+ def get_major_version(self, ns):
17
+ return ns.get_major_version()
18
+
19
+ def get_minor_version(self, ns):
20
+ return ns.get_minor_version()
21
+
22
+ def get_bugfix_version(self, ns):
23
+ return ns.get_bugfix_version()
24
+
25
+ def get_version(self, ns):
26
+ return str(ns.get_major_version()) + "." + str(ns.get_minor_version()) + "." + str(ns.get_bugfix_version())
@@ -11,6 +11,7 @@ class Clip(Interface):
11
11
  clip_id = Interface.save_obj(clip)
12
12
  return {
13
13
  "id": clip_id,
14
+ "name": clip.name,
14
15
  "color": clip.color,
15
16
  "is_audio_clip": clip.is_audio_clip,
16
17
  "is_midi_clip": clip.is_midi_clip,
@@ -10,4 +10,4 @@ class Internal(Interface):
10
10
  return self
11
11
 
12
12
  def get_version(self, ns):
13
- return "2.1.8"
13
+ return "2.3.0"
@@ -82,19 +82,23 @@ class Socket(object):
82
82
  def process(self):
83
83
  try:
84
84
  buffer = bytes()
85
+ num_messages = 0
85
86
  while 1:
86
- data = self._socket.recv(65536)
87
+ data = self._socket.recv(8192)
87
88
  if len(data) and self.input_handler:
88
89
  buffer += data[1:]
90
+ num_messages += 1
89
91
 
90
92
  # \xFF for Live 10 (Python2) and 255 for Live 11 (Python3)
91
93
  if(data[0] == b'\xFF' or data[0] == 255):
92
94
  unzipped = zlib.decompress(buffer)
93
95
  payload = json.loads(unzipped)
94
96
 
95
- self.log_message("Receiving: " + str(payload))
97
+ self.log_message(
98
+ "Receiving from " + str(num_messages) + " messages, " + str(len(buffer)) + " bytes: " + str(payload))
96
99
  self.input_handler(payload)
97
100
  buffer = bytes()
101
+ num_messages = 0
98
102
  except socket.error as e:
99
103
  return
100
104
  except Exception as e:
@@ -1,6 +1,7 @@
1
1
  from __future__ import absolute_import
2
2
  from .Interface import Interface
3
3
  from .Device import Device
4
+ from .Clip import Clip
4
5
  from .ClipSlot import ClipSlot
5
6
 
6
7
 
@@ -16,6 +17,9 @@ class Track(Interface):
16
17
  def __init__(self, c_instance, socket):
17
18
  super(Track, self).__init__(c_instance, socket)
18
19
 
20
+ def get_arrangement_clips(self, ns):
21
+ return list(map(Clip.serialize_clip, ns.arrangement_clips))
22
+
19
23
  def get_devices(self, ns):
20
24
  return list(map(Device.serialize_device, ns.devices))
21
25
 
@@ -0,0 +1,22 @@
1
+ import { Ableton } from "..";
2
+ import { Namespace } from ".";
3
+ export interface GettableProperties {
4
+ bugfix_version: number;
5
+ major_version: number;
6
+ minor_version: number;
7
+ version: string;
8
+ current_dialog_button_count: number;
9
+ current_dialog_message: string;
10
+ open_dialog_count: number;
11
+ }
12
+ export interface TransformedProperties {
13
+ }
14
+ export interface SettableProperties {
15
+ }
16
+ export interface ObservableProperties {
17
+ open_dialog_count: number;
18
+ }
19
+ export declare class Application extends Namespace<GettableProperties, TransformedProperties, SettableProperties, ObservableProperties> {
20
+ constructor(ableton: Ableton);
21
+ pressCurrentDialogButton(index: number): Promise<any>;
22
+ }
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __extends = (this && this.__extends) || (function () {
3
+ var extendStatics = function (d, b) {
4
+ extendStatics = Object.setPrototypeOf ||
5
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
+ return extendStatics(d, b);
8
+ };
9
+ return function (d, b) {
10
+ if (typeof b !== "function" && b !== null)
11
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
+ extendStatics(d, b);
13
+ function __() { this.constructor = d; }
14
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
+ };
16
+ })();
17
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
18
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
19
+ return new (P || (P = Promise))(function (resolve, reject) {
20
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
21
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
22
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
23
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
24
+ });
25
+ };
26
+ var __generator = (this && this.__generator) || function (thisArg, body) {
27
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
28
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
29
+ function verb(n) { return function (v) { return step([n, v]); }; }
30
+ function step(op) {
31
+ if (f) throw new TypeError("Generator is already executing.");
32
+ while (_) try {
33
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
34
+ if (y = 0, t) op = [op[0] & 2, t.value];
35
+ switch (op[0]) {
36
+ case 0: case 1: t = op; break;
37
+ case 4: _.label++; return { value: op[1], done: false };
38
+ case 5: _.label++; y = op[1]; op = [0]; continue;
39
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
40
+ default:
41
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
42
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
43
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
44
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
45
+ if (t[2]) _.ops.pop();
46
+ _.trys.pop(); continue;
47
+ }
48
+ op = body.call(thisArg, _);
49
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
50
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
51
+ }
52
+ };
53
+ Object.defineProperty(exports, "__esModule", { value: true });
54
+ exports.Application = void 0;
55
+ var _1 = require(".");
56
+ var Application = /** @class */ (function (_super) {
57
+ __extends(Application, _super);
58
+ function Application(ableton) {
59
+ return _super.call(this, ableton, "application") || this;
60
+ }
61
+ Application.prototype.pressCurrentDialogButton = function (index) {
62
+ return __awaiter(this, void 0, void 0, function () {
63
+ return __generator(this, function (_a) {
64
+ return [2 /*return*/, this.sendCommand("press_current_dialog_button", [index])];
65
+ });
66
+ });
67
+ };
68
+ return Application;
69
+ }(_1.Namespace));
70
+ exports.Application = Application;
@@ -0,0 +1 @@
1
+ import "jest-extended";
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (_) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ var tests_1 = require("../util/tests");
40
+ require("jest-extended");
41
+ var gettableProps = [
42
+ "major_version",
43
+ "minor_version",
44
+ "bugfix_version",
45
+ "version",
46
+ "open_dialog_count",
47
+ "current_dialog_message",
48
+ "current_dialog_button_count",
49
+ ];
50
+ describe("Application", function () {
51
+ it("should be able to read all properties without erroring", function () { return __awaiter(void 0, void 0, void 0, function () {
52
+ return __generator(this, function (_a) {
53
+ switch (_a.label) {
54
+ case 0: return [4 /*yield*/, tests_1.withAbleton(function (ab) { return __awaiter(void 0, void 0, void 0, function () {
55
+ return __generator(this, function (_a) {
56
+ switch (_a.label) {
57
+ case 0: return [4 /*yield*/, Promise.all(gettableProps.map(function (p) { return ab.application.get(p); }))];
58
+ case 1:
59
+ _a.sent();
60
+ return [2 /*return*/];
61
+ }
62
+ });
63
+ }); })];
64
+ case 1:
65
+ _a.sent();
66
+ return [2 /*return*/];
67
+ }
68
+ });
69
+ }); });
70
+ });
package/ns/clip.d.ts CHANGED
@@ -115,6 +115,7 @@ export interface ObservableProperties {
115
115
  is_recording: boolean;
116
116
  loop_end: number;
117
117
  loop_start: number;
118
+ name: string;
118
119
  pitch_coarse: number;
119
120
  pitch_fine: number;
120
121
  playing_position: number;
@@ -127,6 +128,7 @@ export interface ObservableProperties {
127
128
  }
128
129
  export interface RawClip {
129
130
  id: number;
131
+ name: string;
130
132
  color: number;
131
133
  is_audio_clip: boolean;
132
134
  is_midi_clip: boolean;
package/ns/song.spec.js CHANGED
@@ -143,7 +143,7 @@ describe("Song", function () {
143
143
  switch (_a.label) {
144
144
  case 0:
145
145
  largeArray = [];
146
- for (i = 0; i < 10000; i++) {
146
+ for (i = 0; i < 100000; i++) {
147
147
  largeArray.push(i);
148
148
  }
149
149
  return [4 /*yield*/, ab.song.setData("abletonjs_test", largeArray)];
package/ns/track.d.ts CHANGED
@@ -2,9 +2,11 @@ import { Ableton } from "..";
2
2
  import { Namespace } from ".";
3
3
  import { Device, RawDevice } from "./device";
4
4
  import { ClipSlot, RawClipSlot } from "./clip-slot";
5
+ import { Clip, RawClip } from "./clip";
5
6
  import { Color } from "../util/color";
6
7
  export interface GettableProperties {
7
8
  arm: boolean;
9
+ arrangement_clips: RawClip[];
8
10
  can_be_armed: boolean;
9
11
  can_be_frozen: boolean;
10
12
  can_show_chains: boolean;
@@ -48,6 +50,7 @@ export interface TransformedProperties {
48
50
  color: Color;
49
51
  devices: Device[];
50
52
  clip_slots: ClipSlot[];
53
+ arrangement_clips: Clip[];
51
54
  }
52
55
  export interface SettableProperties {
53
56
  arm: boolean;
@@ -77,6 +80,7 @@ export interface SettableProperties {
77
80
  }
78
81
  export interface ObservableProperties {
79
82
  arm: number;
83
+ arrangement_clips: RawClip[];
80
84
  clip_slots: RawClipSlot[];
81
85
  color_index: number;
82
86
  color: number;
package/ns/track.js CHANGED
@@ -19,6 +19,7 @@ exports.Track = void 0;
19
19
  var _1 = require(".");
20
20
  var device_1 = require("./device");
21
21
  var clip_slot_1 = require("./clip-slot");
22
+ var clip_1 = require("./clip");
22
23
  var color_1 = require("../util/color");
23
24
  var Track = /** @class */ (function (_super) {
24
25
  __extends(Track, _super);
@@ -26,10 +27,13 @@ var Track = /** @class */ (function (_super) {
26
27
  var _this = _super.call(this, ableton, "track", raw.id) || this;
27
28
  _this.raw = raw;
28
29
  _this.transformers = {
30
+ arrangement_clips: function (clips) {
31
+ return clips.map(function (clip) { return new clip_1.Clip(ableton, clip); });
32
+ },
29
33
  color: function (c) { return new color_1.Color(c); },
30
- devices: function (devices) { return devices.map(function (d) { return new device_1.Device(_this.ableton, d); }); },
34
+ devices: function (devices) { return devices.map(function (d) { return new device_1.Device(ableton, d); }); },
31
35
  clip_slots: function (clip_slots) {
32
- return clip_slots.map(function (c) { return new clip_slot_1.ClipSlot(_this.ableton, c); });
36
+ return clip_slots.map(function (c) { return new clip_slot_1.ClipSlot(ableton, c); });
33
37
  },
34
38
  };
35
39
  return _this;
package/package.json CHANGED
@@ -1,10 +1,14 @@
1
1
  {
2
2
  "name": "ableton-js",
3
- "version": "2.1.8",
3
+ "version": "2.3.0",
4
4
  "description": "Control Ableton Live from Node",
5
5
  "main": "index.js",
6
6
  "author": "Leo Bernard <admin@leolabs.org>",
7
7
  "license": "MIT",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/leolabs/ableton-js.git"
11
+ },
8
12
  "files": [
9
13
  "**/*.js",
10
14
  "**/*.d.ts",
@@ -16,7 +20,7 @@
16
20
  "ableton10:launch": "set -- /Applications/Ableton*10* && open \"$1\"",
17
21
  "ableton11:copy-script": "set -- /Applications/Ableton*11*/Contents/App-Resources/MIDI\\ Remote\\ Scripts && rm -rf \"$1/AbletonJS\" && cp -r \"$(pwd)/midi-script\" \"$1/AbletonJS\" && rm -rf \"$1/AbletonJS/_Framework\"",
18
22
  "ableton11:launch": "set -- /Applications/Ableton*11* && open \"$1\"",
19
- "ableton:logs": "tail -f ~/Library/Preferences/Ableton/*/Log.txt | grep -i -e RemoteScriptError -e RemoteScriptMessage | grep -i -e AbletonJS",
23
+ "ableton:logs": "tail -f ~/Library/Preferences/Ableton/*/Log.txt | grep -i -e RemoteScriptError -e RemoteScriptMessage",
20
24
  "ableton:kill": "pkill -KILL -f \"Ableton Live\"",
21
25
  "ableton10:start": "yarn ableton:kill; yarn ableton:clean && yarn ableton10:copy-script && yarn ableton10:launch && yarn ableton:logs",
22
26
  "ableton11:start": "yarn ableton:kill; yarn ableton:clean && yarn ableton11:copy-script && yarn ableton11:launch && yarn ableton:logs",