ableton-js
Advanced tools
Comparing version 3.1.9 to 3.2.0
@@ -7,4 +7,12 @@ ### Changelog | ||
#### [v3.2.0](https://github.com/leolabs/ableton.js/compare/v3.1.9...v3.2.0) | ||
- :package: Upgrade TypeScript and related deps [`f1c3479`](https://github.com/leolabs/ableton.js/commit/f1c34791deaf6ea6f3040d957741756be0cb454c) | ||
- :sparkles: Allow changing the timeout for commands [`d216432`](https://github.com/leolabs/ableton.js/commit/d21643289b53cb727bd438a1a0aebb3f275bcad7) | ||
- :memo: Document class options [`b6c8b7c`](https://github.com/leolabs/ableton.js/commit/b6c8b7c2ed6242f78dd3b5d7343f98c984b1f59c) | ||
#### [v3.1.9](https://github.com/leolabs/ableton.js/compare/v3.1.8...v3.1.9) | ||
> 8 June 2023 | ||
- :bug: Fix issue that could block the main thread in Live sometimes when no client port file exists [`8990a5d`](https://github.com/leolabs/ableton.js/commit/8990a5d00e0ae3a314a385f6748be39dd87cde90) | ||
@@ -11,0 +19,0 @@ - :memo: Update the link to unofficial API docs [`7a32f90`](https://github.com/leolabs/ableton.js/commit/7a32f90d273a3ef05aac22105e253235b66a6c97) |
@@ -21,4 +21,4 @@ /// <reference types="node" /> | ||
} | ||
declare type DisconnectEventType = "realtime" | "heartbeat"; | ||
declare type ConnectEventType = DisconnectEventType | "start"; | ||
type DisconnectEventType = "realtime" | "heartbeat"; | ||
type ConnectEventType = DisconnectEventType | "start"; | ||
interface ConnectionEventEmitter { | ||
@@ -42,6 +42,38 @@ on(e: "connect", l: (t: ConnectEventType) => void): this; | ||
export interface AbletonOptions { | ||
/** | ||
* Name of the file containing the port of the Remote Script. This | ||
* file is expected to be in the OS' tmp directory. | ||
* | ||
* @default ableton-js-server.port | ||
*/ | ||
serverPortFile?: string; | ||
/** | ||
* Name of the file containing the port of the client. This file | ||
* is created in the OS' tmp directory if it doesn't exist yet. | ||
* | ||
* @default ableton-js-client.port | ||
*/ | ||
clientPortFile?: string; | ||
/** | ||
* Defines how regularly ableton-js should ping the Remote Script | ||
* to check if it's still reachable, in milliseconds. | ||
* | ||
* @default 2000 | ||
*/ | ||
heartbeatInterval?: number; | ||
/** | ||
* Defines how long ableton-js waits for an answer from the Remote | ||
* Script after sending a command before throwing a timeout error. | ||
* | ||
* @default 2000 | ||
*/ | ||
commandTimeoutMs?: number; | ||
/** | ||
* Options for the response cache. | ||
*/ | ||
cacheOptions?: LruCache.Options<string, any>; | ||
/** | ||
* Set this to allow ableton-js to log messages. If you set this to | ||
* `console`, log messages are printed to the standard output. | ||
*/ | ||
logger?: Logger; | ||
@@ -99,4 +131,4 @@ } | ||
*/ | ||
sendCommand(command: Omit<Command, "uuid">, timeout?: number): Promise<any>; | ||
sendCachedCommand(command: Omit<Command, "uuid" | "cache">, timeout?: number): Promise<any>; | ||
sendCommand(command: Omit<Command, "uuid">): Promise<any>; | ||
sendCachedCommand(command: Omit<Command, "uuid" | "cache">): Promise<any>; | ||
getProp(ns: string, nsid: string | undefined, prop: string, cache?: boolean): Promise<any>; | ||
@@ -103,0 +135,0 @@ setProp(ns: string, nsid: string | undefined, prop: string, value: any): Promise<any>; |
844
index.js
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
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; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) | ||
to[j] = from[i]; | ||
return to; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -90,73 +7,79 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
exports.getPackageVersion = exports.Ableton = exports.TimeoutError = void 0; | ||
var os_1 = __importDefault(require("os")); | ||
var path_1 = __importDefault(require("path")); | ||
var dgram_1 = __importDefault(require("dgram")); | ||
var events_1 = require("events"); | ||
var uuid_1 = require("uuid"); | ||
var semver_1 = __importDefault(require("semver")); | ||
var zlib_1 = require("zlib"); | ||
var lru_cache_1 = __importDefault(require("lru-cache")); | ||
var fs_1 = require("fs"); | ||
var promises_1 = require("fs/promises"); | ||
var song_1 = require("./ns/song"); | ||
var internal_1 = require("./ns/internal"); | ||
var application_1 = require("./ns/application"); | ||
var midi_1 = require("./ns/midi"); | ||
var package_version_1 = require("./util/package-version"); | ||
var cache_1 = require("./util/cache"); | ||
var SERVER_PORT_FILE = "ableton-js-server.port"; | ||
var CLIENT_PORT_FILE = "ableton-js-client.port"; | ||
var TimeoutError = /** @class */ (function (_super) { | ||
__extends(TimeoutError, _super); | ||
function TimeoutError(message, payload) { | ||
var _this = _super.call(this, message) || this; | ||
_this.message = message; | ||
_this.payload = payload; | ||
return _this; | ||
const os_1 = __importDefault(require("os")); | ||
const path_1 = __importDefault(require("path")); | ||
const dgram_1 = __importDefault(require("dgram")); | ||
const events_1 = require("events"); | ||
const uuid_1 = require("uuid"); | ||
const semver_1 = __importDefault(require("semver")); | ||
const zlib_1 = require("zlib"); | ||
const lru_cache_1 = __importDefault(require("lru-cache")); | ||
const fs_1 = require("fs"); | ||
const promises_1 = require("fs/promises"); | ||
const song_1 = require("./ns/song"); | ||
const internal_1 = require("./ns/internal"); | ||
const application_1 = require("./ns/application"); | ||
const midi_1 = require("./ns/midi"); | ||
const package_version_1 = require("./util/package-version"); | ||
const cache_1 = require("./util/cache"); | ||
const SERVER_PORT_FILE = "ableton-js-server.port"; | ||
const CLIENT_PORT_FILE = "ableton-js-client.port"; | ||
class TimeoutError extends Error { | ||
message; | ||
payload; | ||
constructor(message, payload) { | ||
super(message); | ||
this.message = message; | ||
this.payload = payload; | ||
} | ||
return TimeoutError; | ||
}(Error)); | ||
} | ||
exports.TimeoutError = TimeoutError; | ||
var Ableton = /** @class */ (function (_super) { | ||
__extends(Ableton, _super); | ||
function Ableton(options) { | ||
var _a, _b, _c, _d; | ||
var _this = _super.call(this) || this; | ||
_this.options = options; | ||
_this.msgMap = new Map(); | ||
_this.eventListeners = new Map(); | ||
_this._isConnected = false; | ||
_this.buffer = []; | ||
_this.latency = 0; | ||
_this.song = new song_1.Song(_this); | ||
_this.application = new application_1.Application(_this); | ||
_this.internal = new internal_1.Internal(_this); | ||
_this.midi = new midi_1.Midi(_this); | ||
_this.clientState = "closed"; | ||
_this.cancelDisconnectEvent = false; | ||
_this.logger = options === null || options === void 0 ? void 0 : options.logger; | ||
_this.cache = new lru_cache_1.default(__assign({ max: 500, ttl: 1000 * 60 * 10 }, options === null || options === void 0 ? void 0 : options.cacheOptions)); | ||
_this.clientPortFile = path_1.default.join(os_1.default.tmpdir(), (_b = (_a = _this.options) === null || _a === void 0 ? void 0 : _a.clientPortFile) !== null && _b !== void 0 ? _b : CLIENT_PORT_FILE); | ||
_this.serverPortFile = path_1.default.join(os_1.default.tmpdir(), (_d = (_c = _this.options) === null || _c === void 0 ? void 0 : _c.serverPortFile) !== null && _d !== void 0 ? _d : SERVER_PORT_FILE); | ||
return _this; | ||
class Ableton extends events_1.EventEmitter { | ||
options; | ||
client; | ||
msgMap = new Map(); | ||
eventListeners = new Map(); | ||
heartbeatInterval; | ||
_isConnected = false; | ||
buffer = []; | ||
latency = 0; | ||
serverPort; | ||
cache; | ||
song = new song_1.Song(this); | ||
application = new application_1.Application(this); | ||
internal = new internal_1.Internal(this); | ||
midi = new midi_1.Midi(this); | ||
clientPortFile; | ||
serverPortFile; | ||
logger; | ||
clientState = "closed"; | ||
cancelDisconnectEvent = false; | ||
constructor(options) { | ||
super(); | ||
this.options = options; | ||
this.logger = options?.logger; | ||
this.cache = new lru_cache_1.default({ | ||
max: 500, | ||
ttl: 1000 * 60 * 10, | ||
...options?.cacheOptions, | ||
}); | ||
this.clientPortFile = path_1.default.join(os_1.default.tmpdir(), this.options?.clientPortFile ?? CLIENT_PORT_FILE); | ||
this.serverPortFile = path_1.default.join(os_1.default.tmpdir(), this.options?.serverPortFile ?? SERVER_PORT_FILE); | ||
} | ||
Ableton.prototype.handleConnect = function (type) { | ||
var _a; | ||
handleConnect(type) { | ||
if (!this._isConnected) { | ||
this._isConnected = true; | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.info("Live connected", { type: type }); | ||
this.logger?.info("Live connected", { type }); | ||
this.emit("connect", type); | ||
} | ||
}; | ||
Ableton.prototype.handleDisconnect = function (type) { | ||
var _a; | ||
} | ||
handleDisconnect(type) { | ||
if (this._isConnected) { | ||
this._isConnected = false; | ||
this.eventListeners.clear(); | ||
this.msgMap.forEach(function (msg) { return msg.clearTimeout(); }); | ||
this.msgMap.forEach((msg) => msg.clearTimeout()); | ||
this.msgMap.clear(); | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.info("Live disconnected", { type: type }); | ||
this.logger?.info("Live disconnected", { type }); | ||
this.emit("disconnect", type); | ||
} | ||
}; | ||
} | ||
/** | ||
@@ -166,19 +89,13 @@ * If connected, returns immediately. Otherwise, | ||
*/ | ||
Ableton.prototype.waitForConnection = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
if (this._isConnected) { | ||
return [2 /*return*/]; | ||
} | ||
else { | ||
return [2 /*return*/, Promise.race([ | ||
new Promise(function (res) { return _this.once("connect", res); }), | ||
this.internal.get("ping").catch(function () { return new Promise(function () { }); }), | ||
])]; | ||
} | ||
return [2 /*return*/]; | ||
}); | ||
}); | ||
}; | ||
async waitForConnection() { | ||
if (this._isConnected) { | ||
return; | ||
} | ||
else { | ||
return Promise.race([ | ||
new Promise((res) => this.once("connect", res)), | ||
this.internal.get("ping").catch(() => new Promise(() => { })), | ||
]); | ||
} | ||
} | ||
/** | ||
@@ -191,192 +108,106 @@ * Starts the server and waits for a connection with Live to be established. | ||
*/ | ||
Ableton.prototype.start = function (timeoutMs) { | ||
var _a, _b, _c, _d, _e, _f, _g, _h; | ||
return __awaiter(this, void 0, void 0, function () { | ||
var clientPort, port, error_1, connection, timeout, heartbeat; | ||
var _this = this; | ||
return __generator(this, function (_j) { | ||
switch (_j.label) { | ||
case 0: | ||
if (this.clientState !== "closed") { | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.warn("Tried calling start, but client is already " + this.clientState); | ||
return [2 /*return*/]; | ||
} | ||
this.clientState = "starting"; | ||
this.client = dgram_1.default.createSocket({ type: "udp4" }); | ||
this.client.addListener("message", this.handleIncoming.bind(this)); | ||
this.client.addListener("listening", function () { return __awaiter(_this, void 0, void 0, function () { | ||
var port; | ||
var _a, _b; | ||
return __generator(this, function (_c) { | ||
switch (_c.label) { | ||
case 0: | ||
port = (_a = this.client) === null || _a === void 0 ? void 0 : _a.address().port; | ||
(_b = this.logger) === null || _b === void 0 ? void 0 : _b.info("Client is bound and listening", { port: port }); | ||
// Write used port to a file so Live can read from it | ||
return [4 /*yield*/, promises_1.writeFile(this.clientPortFile, String(port))]; | ||
case 1: | ||
// Write used port to a file so Live can read from it | ||
_c.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); }); | ||
_j.label = 1; | ||
case 1: | ||
_j.trys.push([1, 3, , 4]); | ||
// Try binding to the port that was used last for better start performance | ||
(_b = this.logger) === null || _b === void 0 ? void 0 : _b.info("Checking if a stored port exists", { | ||
file: this.clientPortFile, | ||
}); | ||
return [4 /*yield*/, promises_1.readFile(this.clientPortFile)]; | ||
case 2: | ||
clientPort = _j.sent(); | ||
port = Number(clientPort.toString()); | ||
(_c = this.logger) === null || _c === void 0 ? void 0 : _c.info("Trying to bind to the most recent port", { port: port }); | ||
this.client.bind(port, "127.0.0.1"); | ||
return [3 /*break*/, 4]; | ||
case 3: | ||
error_1 = _j.sent(); | ||
(_d = this.logger) === null || _d === void 0 ? void 0 : _d.info("Couldn't bind to last port, binding to any free port instead", { error: error_1 }); | ||
this.client.bind(undefined, "127.0.0.1"); | ||
return [3 /*break*/, 4]; | ||
case 4: | ||
// Wait for the server port file to exist | ||
return [4 /*yield*/, new Promise(function (res) { return __awaiter(_this, void 0, void 0, function () { | ||
var serverPort, e_1; | ||
var _this = this; | ||
var _a; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
_b.trys.push([0, 2, , 3]); | ||
return [4 /*yield*/, promises_1.readFile(this.serverPortFile)]; | ||
case 1: | ||
serverPort = _b.sent(); | ||
this.serverPort = Number(serverPort.toString()); | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.info("Server port:", { port: this.serverPort }); | ||
res(); | ||
return [3 /*break*/, 3]; | ||
case 2: | ||
e_1 = _b.sent(); | ||
return [3 /*break*/, 3]; | ||
case 3: | ||
// Set up a watcher in case the server port changes | ||
fs_1.watchFile(this.serverPortFile, function (curr) { return __awaiter(_this, void 0, void 0, function () { | ||
var serverPort, newPort; | ||
var _a; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
if (!curr.isFile()) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, promises_1.readFile(this.serverPortFile)]; | ||
case 1: | ||
serverPort = _b.sent(); | ||
newPort = Number(serverPort.toString()); | ||
if (!isNaN(newPort) && newPort !== this.serverPort) { | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.info("Server port changed:", { port: newPort }); | ||
this.serverPort = Number(serverPort.toString()); | ||
} | ||
res(); | ||
_b.label = 2; | ||
case 2: return [2 /*return*/]; | ||
} | ||
}); | ||
}); }); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); })]; | ||
case 5: | ||
// Wait for the server port file to exist | ||
_j.sent(); | ||
(_e = this.logger) === null || _e === void 0 ? void 0 : _e.info("Checking connection..."); | ||
connection = this.waitForConnection(); | ||
if (!timeoutMs) return [3 /*break*/, 7]; | ||
timeout = new Promise(function (_, rej) { | ||
return setTimeout(function () { return rej("Connection timed out."); }, timeoutMs); | ||
}); | ||
return [4 /*yield*/, Promise.race([connection, timeout])]; | ||
case 6: | ||
_j.sent(); | ||
return [3 /*break*/, 9]; | ||
case 7: return [4 /*yield*/, connection]; | ||
case 8: | ||
_j.sent(); | ||
_j.label = 9; | ||
case 9: | ||
(_f = this.logger) === null || _f === void 0 ? void 0 : _f.info("Got connection!"); | ||
this.clientState = "started"; | ||
this.handleConnect("start"); | ||
heartbeat = function () { return __awaiter(_this, void 0, void 0, function () { | ||
var e_2; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, 3, 4]); | ||
return [4 /*yield*/, this.internal.get("ping")]; | ||
case 1: | ||
_a.sent(); | ||
this.handleConnect("heartbeat"); | ||
return [3 /*break*/, 4]; | ||
case 2: | ||
e_2 = _a.sent(); | ||
if (!this.cancelDisconnectEvent) { | ||
this.handleDisconnect("heartbeat"); | ||
} | ||
return [3 /*break*/, 4]; | ||
case 3: | ||
this.cancelDisconnectEvent = false; | ||
return [7 /*endfinally*/]; | ||
case 4: return [2 /*return*/]; | ||
} | ||
}); | ||
}); }; | ||
this.heartbeatInterval = setInterval(heartbeat, (_h = (_g = this.options) === null || _g === void 0 ? void 0 : _g.heartbeatInterval) !== null && _h !== void 0 ? _h : 2000); | ||
heartbeat(); | ||
this.internal | ||
.get("version") | ||
.then(function (v) { | ||
var _a; | ||
var jsVersion = package_version_1.getPackageVersion(); | ||
if (semver_1.default.lt(v, jsVersion)) { | ||
(_a = _this.logger) === null || _a === void 0 ? void 0 : _a.warn("The installed version of your AbletonJS plugin (" + v + ") is lower than the JS library (" + jsVersion + ").", "Please update your AbletonJS plugin to the latest version: https://git.io/JvaOu"); | ||
} | ||
}) | ||
.catch(function () { }); | ||
return [2 /*return*/]; | ||
async start(timeoutMs) { | ||
if (this.clientState !== "closed") { | ||
this.logger?.warn("Tried calling start, but client is already " + this.clientState); | ||
return; | ||
} | ||
this.clientState = "starting"; | ||
this.client = dgram_1.default.createSocket({ type: "udp4" }); | ||
this.client.addListener("message", this.handleIncoming.bind(this)); | ||
this.client.addListener("listening", async () => { | ||
const port = this.client?.address().port; | ||
this.logger?.info("Client is bound and listening", { port }); | ||
// Write used port to a file so Live can read from it | ||
await (0, promises_1.writeFile)(this.clientPortFile, String(port)); | ||
}); | ||
try { | ||
// Try binding to the port that was used last for better start performance | ||
this.logger?.info("Checking if a stored port exists", { | ||
file: this.clientPortFile, | ||
}); | ||
const clientPort = await (0, promises_1.readFile)(this.clientPortFile); | ||
const port = Number(clientPort.toString()); | ||
this.logger?.info("Trying to bind to the most recent port", { port }); | ||
this.client.bind(port, "127.0.0.1"); | ||
} | ||
catch (error) { | ||
this.logger?.info("Couldn't bind to last port, binding to any free port instead", { error }); | ||
this.client.bind(undefined, "127.0.0.1"); | ||
} | ||
// Wait for the server port file to exist | ||
await new Promise(async (res) => { | ||
try { | ||
const serverPort = await (0, promises_1.readFile)(this.serverPortFile); | ||
this.serverPort = Number(serverPort.toString()); | ||
this.logger?.info("Server port:", { port: this.serverPort }); | ||
res(); | ||
} | ||
catch (e) { } | ||
// Set up a watcher in case the server port changes | ||
(0, fs_1.watchFile)(this.serverPortFile, async (curr) => { | ||
if (curr.isFile()) { | ||
const serverPort = await (0, promises_1.readFile)(this.serverPortFile); | ||
const newPort = Number(serverPort.toString()); | ||
if (!isNaN(newPort) && newPort !== this.serverPort) { | ||
this.logger?.info("Server port changed:", { port: newPort }); | ||
this.serverPort = Number(serverPort.toString()); | ||
} | ||
res(); | ||
} | ||
}); | ||
}); | ||
}; | ||
this.logger?.info("Checking connection..."); | ||
const connection = this.waitForConnection(); | ||
if (timeoutMs) { | ||
const timeout = new Promise((_, rej) => setTimeout(() => rej("Connection timed out."), timeoutMs)); | ||
await Promise.race([connection, timeout]); | ||
} | ||
else { | ||
await connection; | ||
} | ||
this.logger?.info("Got connection!"); | ||
this.clientState = "started"; | ||
this.handleConnect("start"); | ||
const heartbeat = async () => { | ||
try { | ||
await this.internal.get("ping"); | ||
this.handleConnect("heartbeat"); | ||
} | ||
catch (e) { | ||
if (!this.cancelDisconnectEvent) { | ||
this.handleDisconnect("heartbeat"); | ||
} | ||
} | ||
finally { | ||
this.cancelDisconnectEvent = false; | ||
} | ||
}; | ||
this.heartbeatInterval = setInterval(heartbeat, this.options?.heartbeatInterval ?? 2000); | ||
heartbeat(); | ||
this.internal | ||
.get("version") | ||
.then((v) => { | ||
const jsVersion = (0, package_version_1.getPackageVersion)(); | ||
if (semver_1.default.lt(v, jsVersion)) { | ||
this.logger?.warn(`The installed version of your AbletonJS plugin (${v}) is lower than the JS library (${jsVersion}).`, "Please update your AbletonJS plugin to the latest version: https://git.io/JvaOu"); | ||
} | ||
}) | ||
.catch(() => { }); | ||
} | ||
/** Closes the client */ | ||
Ableton.prototype.close = function () { | ||
var _a, _b; | ||
return __awaiter(this, void 0, void 0, function () { | ||
var closePromise; | ||
var _this = this; | ||
return __generator(this, function (_c) { | ||
switch (_c.label) { | ||
case 0: | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.info("Closing the client"); | ||
fs_1.unwatchFile(this.serverPortFile); | ||
if (this.heartbeatInterval) { | ||
clearInterval(this.heartbeatInterval); | ||
} | ||
if (!this.client) return [3 /*break*/, 2]; | ||
closePromise = new Promise(function (res) { var _a; return (_a = _this.client) === null || _a === void 0 ? void 0 : _a.once("close", res); }); | ||
this.client.close(); | ||
return [4 /*yield*/, closePromise]; | ||
case 1: | ||
_c.sent(); | ||
_c.label = 2; | ||
case 2: | ||
this.clientState = "closed"; | ||
this._isConnected = false; | ||
(_b = this.logger) === null || _b === void 0 ? void 0 : _b.info("Client closed"); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
}; | ||
async close() { | ||
this.logger?.info("Closing the client"); | ||
(0, fs_1.unwatchFile)(this.serverPortFile); | ||
if (this.heartbeatInterval) { | ||
clearInterval(this.heartbeatInterval); | ||
} | ||
if (this.client) { | ||
const closePromise = new Promise((res) => this.client?.once("close", res)); | ||
this.client.close(); | ||
await closePromise; | ||
} | ||
this.clientState = "closed"; | ||
this._isConnected = false; | ||
this.logger?.info("Client closed"); | ||
} | ||
/** | ||
@@ -386,18 +217,17 @@ * Returns the latency between the last command and its response. | ||
*/ | ||
Ableton.prototype.getPing = function () { | ||
getPing() { | ||
return this.latency; | ||
}; | ||
Ableton.prototype.setPing = function (latency) { | ||
} | ||
setPing(latency) { | ||
this.latency = latency; | ||
this.emit("ping", this.latency); | ||
}; | ||
Ableton.prototype.handleIncoming = function (msg, info) { | ||
var _a; | ||
} | ||
handleIncoming(msg, info) { | ||
try { | ||
var index = msg[0]; | ||
var message = msg.slice(1); | ||
const index = msg[0]; | ||
const message = msg.slice(1); | ||
this.buffer[index] = message; | ||
// 0xFF signals that the end of the buffer has been reached | ||
if (index === 255) { | ||
this.handleUncompressedMessage(zlib_1.unzipSync(Buffer.concat(this.buffer.filter(function (b) { return b; }))).toString()); | ||
this.handleUncompressedMessage((0, zlib_1.unzipSync)(Buffer.concat(this.buffer.filter((b) => b))).toString()); | ||
this.buffer = []; | ||
@@ -408,11 +238,10 @@ } | ||
this.buffer = []; | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.warn("Couldn't handle message:", { error: e }); | ||
this.logger?.warn("Couldn't handle message:", { error: e }); | ||
this.emit("error", e); | ||
} | ||
}; | ||
Ableton.prototype.handleUncompressedMessage = function (msg) { | ||
var _a, _b, _c, _d; | ||
} | ||
handleUncompressedMessage(msg) { | ||
this.emit("raw_message", msg); | ||
var data = JSON.parse(msg); | ||
var functionCallback = this.msgMap.get(data.uuid); | ||
const data = JSON.parse(msg); | ||
const functionCallback = this.msgMap.get(data.uuid); | ||
this.emit("message", data); | ||
@@ -434,4 +263,4 @@ if (data.event === "result" && functionCallback) { | ||
this.cancelDisconnectEvent = true; | ||
if (((_a = data.data) === null || _a === void 0 ? void 0 : _a.port) && ((_b = data.data) === null || _b === void 0 ? void 0 : _b.port) !== this.serverPort) { | ||
(_c = this.logger) === null || _c === void 0 ? void 0 : _c.info("Got new server port via connect:", { | ||
if (data.data?.port && data.data?.port !== this.serverPort) { | ||
this.logger?.info("Got new server port via connect:", { | ||
port: data.data.port, | ||
@@ -443,12 +272,12 @@ }); | ||
} | ||
var eventCallback = this.eventListeners.get(data.event); | ||
const eventCallback = this.eventListeners.get(data.event); | ||
if (eventCallback) { | ||
return eventCallback.forEach(function (cb) { return cb(data.data); }); | ||
return eventCallback.forEach((cb) => cb(data.data)); | ||
} | ||
if (data.uuid) { | ||
(_d = this.logger) === null || _d === void 0 ? void 0 : _d.warn("Message could not be assigned to any request:", { | ||
msg: msg, | ||
this.logger?.warn("Message could not be assigned to any request:", { | ||
msg, | ||
}); | ||
} | ||
}; | ||
} | ||
/** | ||
@@ -458,157 +287,117 @@ * Sends a raw command to Ableton. Usually, you won't need this. | ||
*/ | ||
Ableton.prototype.sendCommand = function (command, timeout) { | ||
if (timeout === void 0) { timeout = 2000; } | ||
return __awaiter(this, void 0, void 0, function () { | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, new Promise(function (res, rej) { | ||
var msgId = uuid_1.v4(); | ||
var payload = __assign({ uuid: msgId }, command); | ||
var msg = JSON.stringify(payload); | ||
var timeoutId = setTimeout(function () { | ||
var arg = JSON.stringify(command.args); | ||
var cls = command.nsid | ||
? command.ns + "(" + command.nsid + ")" | ||
: command.ns; | ||
rej(new TimeoutError([ | ||
"The command " + cls + "." + command.name + "(" + arg + ") timed out after " + timeout + " ms.", | ||
"Please make sure that Ableton is running and that you have the latest", | ||
"version of AbletonJS' MIDI script installed and renamed to \"AbletonJS\".", | ||
].join(" "), payload)); | ||
}, timeout); | ||
var currentTimestamp = Date.now(); | ||
_this.msgMap.set(msgId, { | ||
res: function (result) { | ||
_this.setPing(Date.now() - currentTimestamp); | ||
clearTimeout(timeoutId); | ||
res(result); | ||
}, | ||
rej: rej, | ||
clearTimeout: function () { | ||
clearTimeout(timeoutId); | ||
}, | ||
}); | ||
_this.sendRaw(msg); | ||
})]; | ||
async sendCommand(command) { | ||
return new Promise((res, rej) => { | ||
const msgId = (0, uuid_1.v4)(); | ||
const payload = { | ||
uuid: msgId, | ||
...command, | ||
}; | ||
const msg = JSON.stringify(payload); | ||
const timeout = this.options?.commandTimeoutMs ?? 2000; | ||
const timeoutId = setTimeout(() => { | ||
const arg = JSON.stringify(command.args); | ||
const cls = command.nsid | ||
? `${command.ns}(${command.nsid})` | ||
: command.ns; | ||
rej(new TimeoutError([ | ||
`The command ${cls}.${command.name}(${arg}) timed out after ${timeout} ms.`, | ||
`Please make sure that Ableton is running and that you have the latest`, | ||
`version of AbletonJS' MIDI script installed and renamed to "AbletonJS".`, | ||
].join(" "), payload)); | ||
}, timeout); | ||
const currentTimestamp = Date.now(); | ||
this.msgMap.set(msgId, { | ||
res: (result) => { | ||
this.setPing(Date.now() - currentTimestamp); | ||
clearTimeout(timeoutId); | ||
res(result); | ||
}, | ||
rej, | ||
clearTimeout: () => { | ||
clearTimeout(timeoutId); | ||
}, | ||
}); | ||
this.sendRaw(msg); | ||
}); | ||
}; | ||
Ableton.prototype.sendCachedCommand = function (command, timeout) { | ||
var _a, _b; | ||
return __awaiter(this, void 0, void 0, function () { | ||
var args, cacheKey, cached, result; | ||
return __generator(this, function (_c) { | ||
switch (_c.label) { | ||
case 0: | ||
args = (_b = (_a = command.args) === null || _a === void 0 ? void 0 : _a.prop) !== null && _b !== void 0 ? _b : JSON.stringify(command.args); | ||
cacheKey = [command.ns, command.nsid, args].filter(Boolean).join("/"); | ||
cached = this.cache.get(cacheKey); | ||
return [4 /*yield*/, this.sendCommand(__assign(__assign({}, command), { etag: cached === null || cached === void 0 ? void 0 : cached.etag, cache: true }), timeout)]; | ||
case 1: | ||
result = _c.sent(); | ||
if (cache_1.isCached(result)) { | ||
if (!cached) { | ||
throw new Error("Tried to get an object that isn't cached."); | ||
} | ||
else { | ||
return [2 /*return*/, cached.data]; | ||
} | ||
} | ||
else { | ||
if (result.etag) { | ||
this.cache.set(cacheKey, result); | ||
} | ||
return [2 /*return*/, result.data]; | ||
} | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
} | ||
async sendCachedCommand(command) { | ||
const args = command.args?.prop ?? JSON.stringify(command.args); | ||
const cacheKey = [command.ns, command.nsid, args].filter(Boolean).join("/"); | ||
const cached = this.cache.get(cacheKey); | ||
const result = await this.sendCommand({ | ||
...command, | ||
etag: cached?.etag, | ||
cache: true, | ||
}); | ||
}; | ||
Ableton.prototype.getProp = function (ns, nsid, prop, cache) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var params; | ||
return __generator(this, function (_a) { | ||
params = { ns: ns, nsid: nsid, name: "get_prop", args: { prop: prop } }; | ||
if (cache) { | ||
return [2 /*return*/, this.sendCachedCommand(params)]; | ||
} | ||
else { | ||
return [2 /*return*/, this.sendCommand(params)]; | ||
} | ||
return [2 /*return*/]; | ||
}); | ||
if ((0, cache_1.isCached)(result)) { | ||
if (!cached) { | ||
throw new Error("Tried to get an object that isn't cached."); | ||
} | ||
else { | ||
return cached.data; | ||
} | ||
} | ||
else { | ||
if (result.etag) { | ||
this.cache.set(cacheKey, result); | ||
} | ||
return result.data; | ||
} | ||
} | ||
async getProp(ns, nsid, prop, cache) { | ||
const params = { ns, nsid, name: "get_prop", args: { prop } }; | ||
if (cache) { | ||
return this.sendCachedCommand(params); | ||
} | ||
else { | ||
return this.sendCommand(params); | ||
} | ||
} | ||
async setProp(ns, nsid, prop, value) { | ||
return this.sendCommand({ | ||
ns, | ||
nsid, | ||
name: "set_prop", | ||
args: { prop, value }, | ||
}); | ||
}; | ||
Ableton.prototype.setProp = function (ns, nsid, prop, value) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand({ | ||
ns: ns, | ||
nsid: nsid, | ||
name: "set_prop", | ||
args: { prop: prop, value: value }, | ||
})]; | ||
}); | ||
} | ||
async addPropListener(ns, nsid, prop, listener) { | ||
const eventId = (0, uuid_1.v4)(); | ||
const result = await this.sendCommand({ | ||
ns, | ||
nsid, | ||
name: "add_listener", | ||
args: { prop, nsid, eventId }, | ||
}); | ||
}; | ||
Ableton.prototype.addPropListener = function (ns, nsid, prop, listener) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var eventId, result; | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
eventId = uuid_1.v4(); | ||
return [4 /*yield*/, this.sendCommand({ | ||
ns: ns, | ||
nsid: nsid, | ||
name: "add_listener", | ||
args: { prop: prop, nsid: nsid, eventId: eventId }, | ||
})]; | ||
case 1: | ||
result = _a.sent(); | ||
if (!this.eventListeners.has(result)) { | ||
this.eventListeners.set(result, [listener]); | ||
} | ||
else { | ||
this.eventListeners.set(result, __spreadArray(__spreadArray([], __read(this.eventListeners.get(result))), [ | ||
listener, | ||
])); | ||
} | ||
return [2 /*return*/, function () { return _this.removePropListener(ns, nsid, prop, result, listener); }]; | ||
} | ||
if (!this.eventListeners.has(result)) { | ||
this.eventListeners.set(result, [listener]); | ||
} | ||
else { | ||
this.eventListeners.set(result, [ | ||
...this.eventListeners.get(result), | ||
listener, | ||
]); | ||
} | ||
return () => this.removePropListener(ns, nsid, prop, result, listener); | ||
} | ||
async removePropListener(ns, nsid, prop, eventId, listener) { | ||
const listeners = this.eventListeners.get(eventId); | ||
if (!listeners) { | ||
return false; | ||
} | ||
if (listeners.length > 1) { | ||
this.eventListeners.set(eventId, listeners.filter((l) => l !== listener)); | ||
return true; | ||
} | ||
if (listeners.length === 1) { | ||
this.eventListeners.delete(eventId); | ||
await this.sendCommand({ | ||
ns, | ||
nsid, | ||
name: "remove_listener", | ||
args: { prop, nsid }, | ||
}); | ||
}); | ||
}; | ||
Ableton.prototype.removePropListener = function (ns, nsid, prop, eventId, listener) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var listeners; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
listeners = this.eventListeners.get(eventId); | ||
if (!listeners) { | ||
return [2 /*return*/, false]; | ||
} | ||
if (listeners.length > 1) { | ||
this.eventListeners.set(eventId, listeners.filter(function (l) { return l !== listener; })); | ||
return [2 /*return*/, true]; | ||
} | ||
if (!(listeners.length === 1)) return [3 /*break*/, 2]; | ||
this.eventListeners.delete(eventId); | ||
return [4 /*yield*/, this.sendCommand({ | ||
ns: ns, | ||
nsid: nsid, | ||
name: "remove_listener", | ||
args: { prop: prop, nsid: nsid }, | ||
})]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/, true]; | ||
case 2: return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
}; | ||
return true; | ||
} | ||
} | ||
/** | ||
@@ -619,17 +408,17 @@ * Removes all event listeners that were attached to properties. | ||
*/ | ||
Ableton.prototype.removeAllPropListeners = function () { | ||
removeAllPropListeners() { | ||
this.eventListeners.clear(); | ||
}; | ||
Ableton.prototype.sendRaw = function (msg) { | ||
} | ||
sendRaw(msg) { | ||
if (!this.client || !this.serverPort) { | ||
throw new Error("The client hasn't been started yet. Please call start() first."); | ||
} | ||
var buffer = zlib_1.deflateSync(Buffer.from(msg)); | ||
const buffer = (0, zlib_1.deflateSync)(Buffer.from(msg)); | ||
// Based on this thread, 7500 bytes seems like a safe value | ||
// https://stackoverflow.com/questions/22819214/udp-message-too-long | ||
var byteLimit = 7500; | ||
var chunks = Math.ceil(buffer.byteLength / byteLimit); | ||
const byteLimit = 7500; | ||
const chunks = Math.ceil(buffer.byteLength / byteLimit); | ||
// Split the message into chunks if it becomes too large | ||
for (var i = 0; i < chunks; i++) { | ||
var chunk = Buffer.concat([ | ||
for (let i = 0; i < chunks; i++) { | ||
const chunk = Buffer.concat([ | ||
// Add a counter to the message, the last message is always 255 | ||
@@ -641,10 +430,9 @@ Buffer.alloc(1, i + 1 === chunks ? 255 : i), | ||
} | ||
}; | ||
Ableton.prototype.isConnected = function () { | ||
} | ||
isConnected() { | ||
return this._isConnected; | ||
}; | ||
return Ableton; | ||
}(events_1.EventEmitter)); | ||
} | ||
} | ||
exports.Ableton = Ableton; | ||
var package_version_2 = require("./util/package-version"); | ||
Object.defineProperty(exports, "getPackageVersion", { enumerable: true, get: function () { return package_version_2.getPackageVersion; } }); |
import { Ableton } from ".."; | ||
import { Namespace } from "."; | ||
export declare type DocumentView = "Session" | "Arranger"; | ||
export declare type DetailView = "Detail" | "Detail/Clip" | "Detail/DeviceChain"; | ||
export declare type View = "Browser" | DocumentView | DetailView; | ||
export type DocumentView = "Session" | "Arranger"; | ||
export type DetailView = "Detail" | "Detail/Clip" | "Detail/DeviceChain"; | ||
export type View = "Browser" | DocumentView | DetailView; | ||
export declare enum NavDirection { | ||
@@ -7,0 +7,0 @@ Up = 0, |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
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; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ApplicationView = exports.NavDirection = void 0; | ||
var _1 = require("."); | ||
const _1 = require("."); | ||
var NavDirection; | ||
@@ -62,67 +11,32 @@ (function (NavDirection) { | ||
NavDirection[NavDirection["Right"] = 3] = "Right"; | ||
})(NavDirection = exports.NavDirection || (exports.NavDirection = {})); | ||
var ApplicationView = /** @class */ (function (_super) { | ||
__extends(ApplicationView, _super); | ||
function ApplicationView(ableton) { | ||
return _super.call(this, ableton, "application-view") || this; | ||
})(NavDirection || (exports.NavDirection = NavDirection = {})); | ||
class ApplicationView extends _1.Namespace { | ||
constructor(ableton) { | ||
super(ableton, "application-view"); | ||
} | ||
ApplicationView.prototype.availableMainViews = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCachedCommand("available_main_views")]; | ||
}); | ||
}); | ||
}; | ||
ApplicationView.prototype.focusView = function (view) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("focus_view", [view])]; | ||
}); | ||
}); | ||
}; | ||
ApplicationView.prototype.hideView = function (view) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("hide_view", [view])]; | ||
}); | ||
}); | ||
}; | ||
ApplicationView.prototype.isViewVisible = function (view, mainWindowOnly) { | ||
if (mainWindowOnly === void 0) { mainWindowOnly = true; } | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("is_view_visible", [view, mainWindowOnly])]; | ||
}); | ||
}); | ||
}; | ||
ApplicationView.prototype.scrollView = function (view, direction) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("scroll_view", [direction, view, true])]; | ||
}); | ||
}); | ||
}; | ||
ApplicationView.prototype.showView = function (view) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("show_view", [view])]; | ||
}); | ||
}); | ||
}; | ||
ApplicationView.prototype.toggleBrowse = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("toggle_browse")]; | ||
}); | ||
}); | ||
}; | ||
ApplicationView.prototype.zoomView = function (view, direction) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("zoom_view", [direction, view, true])]; | ||
}); | ||
}); | ||
}; | ||
return ApplicationView; | ||
}(_1.Namespace)); | ||
async availableMainViews() { | ||
return this.sendCachedCommand("available_main_views"); | ||
} | ||
async focusView(view) { | ||
return this.sendCommand("focus_view", [view]); | ||
} | ||
async hideView(view) { | ||
return this.sendCommand("hide_view", [view]); | ||
} | ||
async isViewVisible(view, mainWindowOnly = true) { | ||
return this.sendCommand("is_view_visible", [view, mainWindowOnly]); | ||
} | ||
async scrollView(view, direction) { | ||
return this.sendCommand("scroll_view", [direction, view, true]); | ||
} | ||
async showView(view) { | ||
return this.sendCommand("show_view", [view]); | ||
} | ||
async toggleBrowse() { | ||
return this.sendCommand("toggle_browse"); | ||
} | ||
async zoomView(view, direction) { | ||
return this.sendCommand("zoom_view", [direction, view, true]); | ||
} | ||
} | ||
exports.ApplicationView = ApplicationView; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
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; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tests_1 = require("../util/tests"); | ||
const tests_1 = require("../util/tests"); | ||
require("jest-extended"); | ||
var gettableProps = [ | ||
const gettableProps = [ | ||
"browse_mode", | ||
"focused_document_view", | ||
]; | ||
describe("Application", function () { | ||
it("should be able to read all properties without erroring", function () { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, tests_1.withAbleton(function (ab) { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, Promise.all(gettableProps.map(function (p) { return ab.application.view.get(p); }))]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); })]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
describe("Application", () => { | ||
it("should be able to read all properties without erroring", async () => { | ||
await (0, tests_1.withAbleton)(async (ab) => { | ||
await Promise.all(gettableProps.map((p) => ab.application.view.get(p))); | ||
}); | ||
}); }); | ||
}); | ||
}); |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
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; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Application = void 0; | ||
var _1 = require("."); | ||
var application_view_1 = require("./application-view"); | ||
var Application = /** @class */ (function (_super) { | ||
__extends(Application, _super); | ||
function Application(ableton) { | ||
var _this = _super.call(this, ableton, "application") || this; | ||
_this.view = new application_view_1.ApplicationView(_this.ableton); | ||
return _this; | ||
const _1 = require("."); | ||
const application_view_1 = require("./application-view"); | ||
class Application extends _1.Namespace { | ||
constructor(ableton) { | ||
super(ableton, "application"); | ||
} | ||
Application.prototype.pressCurrentDialogButton = function (index) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("press_current_dialog_button", [index])]; | ||
}); | ||
}); | ||
}; | ||
return Application; | ||
}(_1.Namespace)); | ||
view = new application_view_1.ApplicationView(this.ableton); | ||
async pressCurrentDialogButton(index) { | ||
return this.sendCommand("press_current_dialog_button", [index]); | ||
} | ||
} | ||
exports.Application = Application; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
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; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tests_1 = require("../util/tests"); | ||
const tests_1 = require("../util/tests"); | ||
require("jest-extended"); | ||
var gettableProps = [ | ||
const gettableProps = [ | ||
"major_version", | ||
@@ -50,22 +14,8 @@ "minor_version", | ||
]; | ||
describe("Application", function () { | ||
it("should be able to read all properties without erroring", function () { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, tests_1.withAbleton(function (ab) { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, Promise.all(gettableProps.map(function (p) { return ab.application.get(p); }))]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); })]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
describe("Application", () => { | ||
it("should be able to read all properties without erroring", async () => { | ||
await (0, tests_1.withAbleton)(async (ab) => { | ||
await Promise.all(gettableProps.map((p) => ab.application.get(p))); | ||
}); | ||
}); }); | ||
}); | ||
}); |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ClipSlot = exports.PlayingStatus = void 0; | ||
var _1 = require("."); | ||
var color_1 = require("../util/color"); | ||
var clip_1 = require("./clip"); | ||
const _1 = require("."); | ||
const color_1 = require("../util/color"); | ||
const clip_1 = require("./clip"); | ||
var PlayingStatus; | ||
@@ -27,19 +12,18 @@ (function (PlayingStatus) { | ||
PlayingStatus["Recording"] = "recording"; | ||
})(PlayingStatus = exports.PlayingStatus || (exports.PlayingStatus = {})); | ||
})(PlayingStatus || (exports.PlayingStatus = PlayingStatus = {})); | ||
/** | ||
* This class represents an entry in Live's Session view matrix. | ||
*/ | ||
var ClipSlot = /** @class */ (function (_super) { | ||
__extends(ClipSlot, _super); | ||
function ClipSlot(ableton, raw) { | ||
var _this = _super.call(this, ableton, "clip_slot", raw.id) || this; | ||
_this.raw = raw; | ||
_this.transformers = { | ||
clip: function (c) { return (c ? new clip_1.Clip(ableton, c) : null); }, | ||
color: function (c) { return new color_1.Color(c); }, | ||
class ClipSlot extends _1.Namespace { | ||
raw; | ||
constructor(ableton, raw) { | ||
super(ableton, "clip_slot", raw.id); | ||
this.raw = raw; | ||
this.transformers = { | ||
clip: (c) => (c ? new clip_1.Clip(ableton, c) : null), | ||
color: (c) => new color_1.Color(c), | ||
}; | ||
_this.cachedProps = { | ||
this.cachedProps = { | ||
clip: true, | ||
}; | ||
return _this; | ||
} | ||
@@ -50,5 +34,5 @@ /** | ||
*/ | ||
ClipSlot.prototype.createClip = function (length) { | ||
createClip(length) { | ||
return this.sendCommand("create_clip", [length]); | ||
}; | ||
} | ||
/** | ||
@@ -58,8 +42,8 @@ * Removes the clip contained in the slot. | ||
*/ | ||
ClipSlot.prototype.deleteClip = function () { | ||
deleteClip() { | ||
return this.sendCommand("delete_clip"); | ||
}; | ||
ClipSlot.prototype.duplicateClipTo = function (slot) { | ||
} | ||
duplicateClipTo(slot) { | ||
return this.sendCommand("duplicate_clip_to", { slot_id: slot.raw.id }); | ||
}; | ||
} | ||
/** | ||
@@ -69,5 +53,5 @@ * Fire a Clip if this Clipslot owns one, | ||
*/ | ||
ClipSlot.prototype.fire = function () { | ||
fire() { | ||
return this.sendCommand("fire"); | ||
}; | ||
} | ||
/** | ||
@@ -77,5 +61,5 @@ * Set the ClipSlot's fire button state directly. | ||
*/ | ||
ClipSlot.prototype.setFireButtonState = function (state) { | ||
setFireButtonState(state) { | ||
return this.sendCommand("set_fire_button_state", [state]); | ||
}; | ||
} | ||
/** | ||
@@ -85,7 +69,6 @@ * Stop playing the contained Clip, | ||
*/ | ||
ClipSlot.prototype.stop = function () { | ||
stop() { | ||
return this.sendCommand("stop"); | ||
}; | ||
return ClipSlot; | ||
}(_1.Namespace)); | ||
} | ||
} | ||
exports.ClipSlot = ClipSlot; |
200
ns/clip.js
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
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; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Clip = exports.LaunchQuantization = exports.LaunchMode = exports.WarpMode = void 0; | ||
var _1 = require("."); | ||
var color_1 = require("../util/color"); | ||
var note_1 = require("../util/note"); | ||
const _1 = require("."); | ||
const color_1 = require("../util/color"); | ||
const note_1 = require("../util/note"); | ||
var WarpMode; | ||
@@ -66,3 +15,3 @@ (function (WarpMode) { | ||
WarpMode[WarpMode["ComplexPro"] = 6] = "ComplexPro"; | ||
})(WarpMode = exports.WarpMode || (exports.WarpMode = {})); | ||
})(WarpMode || (exports.WarpMode = WarpMode = {})); | ||
var LaunchMode; | ||
@@ -74,3 +23,3 @@ (function (LaunchMode) { | ||
LaunchMode[LaunchMode["Repeat"] = 3] = "Repeat"; | ||
})(LaunchMode = exports.LaunchMode || (exports.LaunchMode = {})); | ||
})(LaunchMode || (exports.LaunchMode = LaunchMode = {})); | ||
var LaunchQuantization; | ||
@@ -93,17 +42,16 @@ (function (LaunchQuantization) { | ||
LaunchQuantization[LaunchQuantization["QThirtySecond"] = 14] = "QThirtySecond"; | ||
})(LaunchQuantization = exports.LaunchQuantization || (exports.LaunchQuantization = {})); | ||
})(LaunchQuantization || (exports.LaunchQuantization = LaunchQuantization = {})); | ||
/** | ||
* This class represents an entry in Live's Session view matrix. | ||
*/ | ||
var Clip = /** @class */ (function (_super) { | ||
__extends(Clip, _super); | ||
function Clip(ableton, raw) { | ||
var _this = _super.call(this, ableton, "clip", raw.id) || this; | ||
_this.raw = raw; | ||
_this.transformers = { | ||
color: function (c) { return new color_1.Color(c); }, | ||
notes: function (n) { return n.map(note_1.tupleToNote); }, | ||
selected_notes: function (n) { return n.map(note_1.tupleToNote); }, | ||
class Clip extends _1.Namespace { | ||
raw; | ||
constructor(ableton, raw) { | ||
super(ableton, "clip", raw.id); | ||
this.raw = raw; | ||
this.transformers = { | ||
color: (c) => new color_1.Color(c), | ||
notes: (n) => n.map(note_1.tupleToNote), | ||
selected_notes: (n) => n.map(note_1.tupleToNote), | ||
}; | ||
return _this; | ||
} | ||
@@ -115,17 +63,17 @@ /** | ||
*/ | ||
Clip.prototype.beatToSampleTime = function (beats) { | ||
beatToSampleTime(beats) { | ||
return this.sendCommand("beat_to_sample_time", [beats]); | ||
}; | ||
} | ||
/** | ||
* Clears all envelopes for this clip. | ||
*/ | ||
Clip.prototype.clearAllEnvelopes = function () { | ||
clearAllEnvelopes() { | ||
return this.sendCommand("clear_all_envelopes"); | ||
}; | ||
} | ||
/** | ||
* Clears the envelope of this clip's given parameter. | ||
*/ | ||
Clip.prototype.clearEnvelope = function (parameter) { | ||
return this.sendCommand("clear_envelope", { parameter: parameter }); | ||
}; | ||
clearEnvelope(parameter) { | ||
return this.sendCommand("clear_envelope", { parameter }); | ||
} | ||
/** | ||
@@ -136,3 +84,3 @@ * Creates an envelope for a given parameter and returns it. | ||
*/ | ||
Clip.prototype.createAutomationEnvelope = function () { }; | ||
createAutomationEnvelope() { } | ||
/** | ||
@@ -144,11 +92,11 @@ * Crops the clip. The region that is cropped depends on whether | ||
*/ | ||
Clip.prototype.crop = function () { | ||
crop() { | ||
return this.sendCommand("crop"); | ||
}; | ||
} | ||
/** | ||
* Deselects all notes present in the clip. | ||
*/ | ||
Clip.prototype.deselectAllNotes = function () { | ||
deselectAllNotes() { | ||
return this.sendCommand("deselect_all_notes"); | ||
}; | ||
} | ||
/** | ||
@@ -158,5 +106,5 @@ * Makes the loop twice as long and duplicates notes and envelopes. | ||
*/ | ||
Clip.prototype.duplicateLoop = function () { | ||
duplicateLoop() { | ||
return this.sendCommand("duplicate_loop"); | ||
}; | ||
} | ||
/** | ||
@@ -169,5 +117,3 @@ * Duplicates the notes in the specified region to the destination_time. | ||
*/ | ||
Clip.prototype.duplicateRegion = function (start, length, destinationTime, pitch, transpositionAmount) { | ||
if (pitch === void 0) { pitch = -1; } | ||
if (transpositionAmount === void 0) { transpositionAmount = 0; } | ||
duplicateRegion(start, length, destinationTime, pitch = -1, transpositionAmount = 0) { | ||
return this.sendCommand("duplicate_region", [ | ||
@@ -180,30 +126,21 @@ start, | ||
]); | ||
}; | ||
} | ||
/** | ||
* Starts playing this clip. | ||
*/ | ||
Clip.prototype.fire = function () { | ||
fire() { | ||
return this.sendCommand("fire"); | ||
}; | ||
} | ||
/** | ||
* Returns all notes that match the given range. | ||
*/ | ||
Clip.prototype.getNotes = function (fromTime, fromPitch, timeSpan, pitchSpan) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var notes; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.sendCommand("get_notes", { | ||
from_time: fromTime, | ||
from_pitch: fromPitch, | ||
time_span: timeSpan, | ||
pitch_span: pitchSpan, | ||
})]; | ||
case 1: | ||
notes = _a.sent(); | ||
return [2 /*return*/, notes.map(note_1.tupleToNote)]; | ||
} | ||
}); | ||
async getNotes(fromTime, fromPitch, timeSpan, pitchSpan) { | ||
const notes = await this.sendCommand("get_notes", { | ||
from_time: fromTime, | ||
from_pitch: fromPitch, | ||
time_span: timeSpan, | ||
pitch_span: pitchSpan, | ||
}); | ||
}; | ||
return notes.map(note_1.tupleToNote); | ||
} | ||
/** | ||
@@ -213,21 +150,21 @@ * Jump forward or backward by the specified relative amount in beats. | ||
*/ | ||
Clip.prototype.movePlayingPos = function (amount) { | ||
movePlayingPos(amount) { | ||
return this.sendCommand("move_playing_pos", [amount]); | ||
}; | ||
} | ||
/** | ||
* Quantizes all notes in a clip or aligns warp markers. | ||
*/ | ||
Clip.prototype.quantize = function (grid, amount) { | ||
quantize(grid, amount) { | ||
return this.sendCommand("quantize", [grid, amount]); | ||
}; | ||
} | ||
/** | ||
* Quantizes all the notes of a given pitch. | ||
*/ | ||
Clip.prototype.quantizePitch = function (pitch, grid, amount) { | ||
quantizePitch(pitch, grid, amount) { | ||
return this.sendCommand("quantize_pitch", [pitch, grid, amount]); | ||
}; | ||
} | ||
/** | ||
* Deletes all notes that start in the given area. | ||
*/ | ||
Clip.prototype.removeNotes = function (fromTime, fromPitch, timeSpan, pitchSpan) { | ||
removeNotes(fromTime, fromPitch, timeSpan, pitchSpan) { | ||
return this.sendCommand("remove_notes", [ | ||
@@ -239,11 +176,11 @@ fromTime, | ||
]); | ||
}; | ||
} | ||
/** | ||
* Replaces selected notes with an array of new notes. | ||
*/ | ||
Clip.prototype.replaceSelectedNotes = function (notes) { | ||
replaceSelectedNotes(notes) { | ||
return this.sendCommand("replace_selected_notes", { | ||
notes: notes.map(note_1.noteToTuple), | ||
}); | ||
}; | ||
} | ||
/** | ||
@@ -254,5 +191,5 @@ * Available for audio clips only. | ||
*/ | ||
Clip.prototype.sampleToBeatTime = function (sampleTime) { | ||
sampleToBeatTime(sampleTime) { | ||
return this.sendCommand("sample_to_beat_time", [sampleTime]); | ||
}; | ||
} | ||
/** | ||
@@ -264,5 +201,5 @@ * Scrubs inside a clip. | ||
*/ | ||
Clip.prototype.scrub = function (position) { | ||
scrub(position) { | ||
return this.sendCommand("scrub", [position]); | ||
}; | ||
} | ||
/** | ||
@@ -273,11 +210,11 @@ * Available for audio clips only. | ||
*/ | ||
Clip.prototype.secondsToSampleTime = function (seconds) { | ||
secondsToSampleTime(seconds) { | ||
return this.sendCommand("seconds_to_sample_time", [seconds]); | ||
}; | ||
} | ||
/** | ||
* Selects all notes present in the clip. | ||
*/ | ||
Clip.prototype.selectAllNotes = function () { | ||
selectAllNotes() { | ||
return this.sendCommand("select_all_notes"); | ||
}; | ||
} | ||
/** | ||
@@ -287,25 +224,24 @@ * Set the clip's fire button state directly. | ||
*/ | ||
Clip.prototype.setFireButtonState = function (state) { | ||
setFireButtonState(state) { | ||
return this.sendCommand("set_fire_button_state", [state]); | ||
}; | ||
} | ||
/** | ||
* Adds the given notes to the clip. | ||
*/ | ||
Clip.prototype.setNotes = function (notes) { | ||
setNotes(notes) { | ||
return this.sendCommand("set_notes", { notes: notes.map(note_1.noteToTuple) }); | ||
}; | ||
} | ||
/** | ||
* Stop playig this clip. | ||
*/ | ||
Clip.prototype.stop = function () { | ||
stop() { | ||
return this.sendCommand("stop"); | ||
}; | ||
} | ||
/** | ||
* Stops the current scrub. | ||
*/ | ||
Clip.prototype.stopScrub = function () { | ||
stopScrub() { | ||
return this.sendCommand("stop_scrub"); | ||
}; | ||
return Clip; | ||
}(_1.Namespace)); | ||
} | ||
} | ||
exports.Clip = Clip; |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
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; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.CuePoint = void 0; | ||
var _1 = require("."); | ||
var CuePoint = /** @class */ (function (_super) { | ||
__extends(CuePoint, _super); | ||
function CuePoint(ableton, raw) { | ||
var _this = _super.call(this, ableton, "cue-point", raw.id) || this; | ||
_this.raw = raw; | ||
return _this; | ||
const _1 = require("."); | ||
class CuePoint extends _1.Namespace { | ||
raw; | ||
constructor(ableton, raw) { | ||
super(ableton, "cue-point", raw.id); | ||
this.raw = raw; | ||
} | ||
CuePoint.prototype.jump = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("jump")]; | ||
}); | ||
}); | ||
}; | ||
return CuePoint; | ||
}(_1.Namespace)); | ||
async jump() { | ||
return this.sendCommand("jump"); | ||
} | ||
} | ||
exports.CuePoint = CuePoint; |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.DeviceParameter = exports.ParameterState = exports.AutomationState = void 0; | ||
var _1 = require("."); | ||
const _1 = require("."); | ||
var AutomationState; | ||
@@ -25,3 +10,3 @@ (function (AutomationState) { | ||
AutomationState[AutomationState["Overridden"] = 2] = "Overridden"; | ||
})(AutomationState = exports.AutomationState || (exports.AutomationState = {})); | ||
})(AutomationState || (exports.AutomationState = AutomationState = {})); | ||
var ParameterState; | ||
@@ -32,12 +17,10 @@ (function (ParameterState) { | ||
ParameterState[ParameterState["Irrelevant"] = 2] = "Irrelevant"; | ||
})(ParameterState = exports.ParameterState || (exports.ParameterState = {})); | ||
var DeviceParameter = /** @class */ (function (_super) { | ||
__extends(DeviceParameter, _super); | ||
function DeviceParameter(ableton, raw) { | ||
var _this = _super.call(this, ableton, "device-parameter", raw.id) || this; | ||
_this.raw = raw; | ||
return _this; | ||
})(ParameterState || (exports.ParameterState = ParameterState = {})); | ||
class DeviceParameter extends _1.Namespace { | ||
raw; | ||
constructor(ableton, raw) { | ||
super(ableton, "device-parameter", raw.id); | ||
this.raw = raw; | ||
} | ||
return DeviceParameter; | ||
}(_1.Namespace)); | ||
} | ||
exports.DeviceParameter = DeviceParameter; |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Device = exports.DeviceType = void 0; | ||
var _1 = require("."); | ||
var device_parameter_1 = require("./device-parameter"); | ||
const _1 = require("."); | ||
const device_parameter_1 = require("./device-parameter"); | ||
var DeviceType; | ||
@@ -27,18 +12,16 @@ (function (DeviceType) { | ||
DeviceType["Undefined"] = "undefined"; | ||
})(DeviceType = exports.DeviceType || (exports.DeviceType = {})); | ||
var Device = /** @class */ (function (_super) { | ||
__extends(Device, _super); | ||
function Device(ableton, raw) { | ||
var _this = _super.call(this, ableton, "device", raw.id) || this; | ||
_this.raw = raw; | ||
_this.transformers = { | ||
parameters: function (ps) { return ps.map(function (p) { return new device_parameter_1.DeviceParameter(ableton, p); }); }, | ||
})(DeviceType || (exports.DeviceType = DeviceType = {})); | ||
class Device extends _1.Namespace { | ||
raw; | ||
constructor(ableton, raw) { | ||
super(ableton, "device", raw.id); | ||
this.raw = raw; | ||
this.transformers = { | ||
parameters: (ps) => ps.map((p) => new device_parameter_1.DeviceParameter(ableton, p)), | ||
}; | ||
_this.cachedProps = { | ||
this.cachedProps = { | ||
parameters: true, | ||
}; | ||
return _this; | ||
} | ||
return Device; | ||
}(_1.Namespace)); | ||
} | ||
exports.Device = Device; |
@@ -22,3 +22,3 @@ import { Ableton } from ".."; | ||
[k: string]: any; | ||
}, etag?: string, timeout?: number): Promise<any>; | ||
}, etag?: string): Promise<any>; | ||
/** | ||
@@ -30,3 +30,3 @@ * Sends a raw function invocation to Ableton and expects the | ||
[k: string]: any; | ||
}, timeout?: number): Promise<any>; | ||
}): Promise<any>; | ||
} |
145
ns/index.js
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
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; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Namespace = void 0; | ||
var Namespace = /** @class */ (function () { | ||
function Namespace(ableton, ns, nsid) { | ||
class Namespace { | ||
ableton; | ||
ns; | ||
nsid; | ||
transformers = {}; | ||
cachedProps = {}; | ||
constructor(ableton, ns, nsid) { | ||
this.ableton = ableton; | ||
this.ns = ns; | ||
this.nsid = nsid; | ||
this.transformers = {}; | ||
this.cachedProps = {}; | ||
} | ||
Namespace.prototype.get = function (prop) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var cache, res, transformer; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
cache = !!this.cachedProps[prop]; | ||
return [4 /*yield*/, this.ableton.getProp(this.ns, this.nsid, String(prop), cache)]; | ||
case 1: | ||
res = _a.sent(); | ||
transformer = this.transformers[prop]; | ||
if (res !== null && transformer) { | ||
return [2 /*return*/, transformer(res)]; | ||
} | ||
else { | ||
return [2 /*return*/, res]; | ||
} | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
async get(prop) { | ||
const cache = !!this.cachedProps[prop]; | ||
const res = await this.ableton.getProp(this.ns, this.nsid, String(prop), cache); | ||
const transformer = this.transformers[prop]; | ||
if (res !== null && transformer) { | ||
return transformer(res); | ||
} | ||
else { | ||
return res; | ||
} | ||
} | ||
async set(prop, value) { | ||
return this.ableton.setProp(this.ns, this.nsid, String(prop), value); | ||
} | ||
async addListener(prop, listener) { | ||
const transformer = this.transformers[prop]; | ||
return this.ableton.addPropListener(this.ns, this.nsid, String(prop), (data) => { | ||
if (data !== null && transformer) { | ||
listener(transformer(data)); | ||
} | ||
else { | ||
listener(data); | ||
} | ||
}); | ||
}; | ||
Namespace.prototype.set = function (prop, value) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.ableton.setProp(this.ns, this.nsid, String(prop), value)]; | ||
}); | ||
}); | ||
}; | ||
Namespace.prototype.addListener = function (prop, listener) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var transformer; | ||
return __generator(this, function (_a) { | ||
transformer = this.transformers[prop]; | ||
return [2 /*return*/, this.ableton.addPropListener(this.ns, this.nsid, String(prop), function (data) { | ||
if (data !== null && transformer) { | ||
listener(transformer(data)); | ||
} | ||
else { | ||
listener(data); | ||
} | ||
})]; | ||
}); | ||
}); | ||
}; | ||
} | ||
/** | ||
@@ -97,9 +44,11 @@ * Sends a raw function invocation to Ableton. | ||
*/ | ||
Namespace.prototype.sendCommand = function (name, args, etag, timeout) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.ableton.sendCommand({ ns: this.ns, nsid: this.nsid, name: name, args: args, etag: etag }, timeout)]; | ||
}); | ||
async sendCommand(name, args, etag) { | ||
return this.ableton.sendCommand({ | ||
ns: this.ns, | ||
nsid: this.nsid, | ||
name, | ||
args, | ||
etag, | ||
}); | ||
}; | ||
} | ||
/** | ||
@@ -109,11 +58,11 @@ * Sends a raw function invocation to Ableton and expects the | ||
*/ | ||
Namespace.prototype.sendCachedCommand = function (name, args, timeout) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.ableton.sendCachedCommand({ ns: this.ns, nsid: this.nsid, name: name, args: args }, timeout)]; | ||
}); | ||
async sendCachedCommand(name, args) { | ||
return this.ableton.sendCachedCommand({ | ||
ns: this.ns, | ||
nsid: this.nsid, | ||
name, | ||
args, | ||
}); | ||
}; | ||
return Namespace; | ||
}()); | ||
} | ||
} | ||
exports.Namespace = Namespace; |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
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; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -58,25 +7,14 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
exports.Internal = void 0; | ||
var _1 = require("."); | ||
var package_version_1 = require("../util/package-version"); | ||
var semver_1 = __importDefault(require("semver")); | ||
var Internal = /** @class */ (function (_super) { | ||
__extends(Internal, _super); | ||
function Internal(ableton) { | ||
return _super.call(this, ableton, "internal") || this; | ||
const _1 = require("."); | ||
const package_version_1 = require("../util/package-version"); | ||
const semver_1 = __importDefault(require("semver")); | ||
class Internal extends _1.Namespace { | ||
constructor(ableton) { | ||
super(ableton, "internal"); | ||
} | ||
Internal.prototype.isPluginUpToDate = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var pluginVersion; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.get("version")]; | ||
case 1: | ||
pluginVersion = _a.sent(); | ||
return [2 /*return*/, !semver_1.default.lt(pluginVersion, package_version_1.getPackageVersion())]; | ||
} | ||
}); | ||
}); | ||
}; | ||
return Internal; | ||
}(_1.Namespace)); | ||
async isPluginUpToDate() { | ||
const pluginVersion = await this.get("version"); | ||
return !semver_1.default.lt(pluginVersion, (0, package_version_1.getPackageVersion)()); | ||
} | ||
} | ||
exports.Internal = Internal; |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Midi = exports.MidiMessage = exports.MidiCommand = void 0; | ||
var _1 = require("."); | ||
const _1 = require("."); | ||
var MidiCommand; | ||
@@ -41,7 +26,8 @@ (function (MidiCommand) { | ||
MidiCommand[MidiCommand["SystemReset"] = 255] = "SystemReset"; | ||
})(MidiCommand = exports.MidiCommand || (exports.MidiCommand = {})); | ||
var MidiMessage = /** @class */ (function () { | ||
function MidiMessage(raw) { | ||
this.parameter1 = null; | ||
this.parameter2 = null; | ||
})(MidiCommand || (exports.MidiCommand = MidiCommand = {})); | ||
class MidiMessage { | ||
command; | ||
parameter1 = null; | ||
parameter2 = null; | ||
constructor(raw) { | ||
switch (raw.bytes.length) { | ||
@@ -67,3 +53,3 @@ case 0: | ||
} | ||
MidiMessage.prototype.toCC = function () { | ||
toCC() { | ||
if (this.command !== MidiCommand.ControlChange) { | ||
@@ -77,4 +63,4 @@ throw "not a midi CC message"; | ||
}; | ||
}; | ||
MidiMessage.prototype.toNote = function () { | ||
} | ||
toNote() { | ||
if (this.command !== MidiCommand.NoteOn && | ||
@@ -89,17 +75,13 @@ this.command !== MidiCommand.NoteOff) { | ||
}; | ||
}; | ||
return MidiMessage; | ||
}()); | ||
} | ||
} | ||
exports.MidiMessage = MidiMessage; | ||
var Midi = /** @class */ (function (_super) { | ||
__extends(Midi, _super); | ||
function Midi(ableton) { | ||
var _this = _super.call(this, ableton, "midi") || this; | ||
_this.transformers = { | ||
midi: function (msg) { return new MidiMessage(msg); }, | ||
class Midi extends _1.Namespace { | ||
constructor(ableton) { | ||
super(ableton, "midi"); | ||
this.transformers = { | ||
midi: (msg) => new MidiMessage(msg), | ||
}; | ||
return _this; | ||
} | ||
return Midi; | ||
}(_1.Namespace)); | ||
} | ||
exports.Midi = Midi; |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.MixerDevice = exports.CrossfadeAssignment = exports.PanningMode = void 0; | ||
var _1 = require("."); | ||
var device_parameter_1 = require("./device-parameter"); | ||
const _1 = require("."); | ||
const device_parameter_1 = require("./device-parameter"); | ||
var PanningMode; | ||
@@ -25,3 +10,3 @@ (function (PanningMode) { | ||
PanningMode[PanningMode["StereoSplit"] = 1] = "StereoSplit"; | ||
})(PanningMode = exports.PanningMode || (exports.PanningMode = {})); | ||
})(PanningMode || (exports.PanningMode = PanningMode = {})); | ||
var CrossfadeAssignment; | ||
@@ -32,23 +17,21 @@ (function (CrossfadeAssignment) { | ||
CrossfadeAssignment[CrossfadeAssignment["B"] = 2] = "B"; | ||
})(CrossfadeAssignment = exports.CrossfadeAssignment || (exports.CrossfadeAssignment = {})); | ||
var MixerDevice = /** @class */ (function (_super) { | ||
__extends(MixerDevice, _super); | ||
function MixerDevice(ableton, raw) { | ||
var _this = _super.call(this, ableton, "mixer-device", raw.id) || this; | ||
_this.raw = raw; | ||
_this.transformers = { | ||
crossfader: function (v) { return new device_parameter_1.DeviceParameter(ableton, v); }, | ||
cue_volume: function (v) { return new device_parameter_1.DeviceParameter(ableton, v); }, | ||
left_split_stereo: function (v) { return new device_parameter_1.DeviceParameter(ableton, v); }, | ||
panning: function (v) { return new device_parameter_1.DeviceParameter(ableton, v); }, | ||
right_split_stereo: function (v) { return new device_parameter_1.DeviceParameter(ableton, v); }, | ||
sends: function (v) { return v.map(function (s) { return new device_parameter_1.DeviceParameter(ableton, s); }); }, | ||
song_tempo: function (v) { return new device_parameter_1.DeviceParameter(ableton, v); }, | ||
track_activator: function (v) { return new device_parameter_1.DeviceParameter(ableton, v); }, | ||
volume: function (v) { return new device_parameter_1.DeviceParameter(ableton, v); }, | ||
})(CrossfadeAssignment || (exports.CrossfadeAssignment = CrossfadeAssignment = {})); | ||
class MixerDevice extends _1.Namespace { | ||
raw; | ||
constructor(ableton, raw) { | ||
super(ableton, "mixer-device", raw.id); | ||
this.raw = raw; | ||
this.transformers = { | ||
crossfader: (v) => new device_parameter_1.DeviceParameter(ableton, v), | ||
cue_volume: (v) => new device_parameter_1.DeviceParameter(ableton, v), | ||
left_split_stereo: (v) => new device_parameter_1.DeviceParameter(ableton, v), | ||
panning: (v) => new device_parameter_1.DeviceParameter(ableton, v), | ||
right_split_stereo: (v) => new device_parameter_1.DeviceParameter(ableton, v), | ||
sends: (v) => v.map((s) => new device_parameter_1.DeviceParameter(ableton, s)), | ||
song_tempo: (v) => new device_parameter_1.DeviceParameter(ableton, v), | ||
track_activator: (v) => new device_parameter_1.DeviceParameter(ableton, v), | ||
volume: (v) => new device_parameter_1.DeviceParameter(ableton, v), | ||
}; | ||
return _this; | ||
} | ||
return MixerDevice; | ||
}(_1.Namespace)); | ||
} | ||
exports.MixerDevice = MixerDevice; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
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; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tests_1 = require("../util/tests"); | ||
const tests_1 = require("../util/tests"); | ||
require("jest-extended"); | ||
var gettableProps = [ | ||
const gettableProps = [ | ||
//"crossfade_assign", (not applicable to the master track) | ||
@@ -54,29 +18,10 @@ "crossfader", | ||
]; | ||
describe("Mixer Device", function () { | ||
it("should be able to read all properties without erroring", function () { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, tests_1.withAbleton(function (ab) { return __awaiter(void 0, void 0, void 0, function () { | ||
var masterTrack, mixerDevice; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, ab.song.get("master_track")]; | ||
case 1: | ||
masterTrack = _a.sent(); | ||
return [4 /*yield*/, masterTrack.get("mixer_device")]; | ||
case 2: | ||
mixerDevice = _a.sent(); | ||
return [4 /*yield*/, Promise.all(gettableProps.map(function (p) { return mixerDevice.get(p); }))]; | ||
case 3: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); })]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
describe("Mixer Device", () => { | ||
it("should be able to read all properties without erroring", async () => { | ||
await (0, tests_1.withAbleton)(async (ab) => { | ||
const masterTrack = await ab.song.get("master_track"); | ||
const mixerDevice = await masterTrack.get("mixer_device"); | ||
await Promise.all(gettableProps.map((p) => mixerDevice.get(p))); | ||
}); | ||
}); }); | ||
}); | ||
}); |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
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; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Scene = void 0; | ||
var _1 = require("."); | ||
var clip_slot_1 = require("./clip-slot"); | ||
var Scene = /** @class */ (function (_super) { | ||
__extends(Scene, _super); | ||
function Scene(ableton, raw) { | ||
var _this = _super.call(this, ableton, "scene", raw.id) || this; | ||
_this.raw = raw; | ||
_this.transformers = { | ||
clip_slots: function (clip_slots) { | ||
return clip_slots.map(function (c) { return new clip_slot_1.ClipSlot(_this.ableton, c); }); | ||
}, | ||
const _1 = require("."); | ||
const clip_slot_1 = require("./clip-slot"); | ||
class Scene extends _1.Namespace { | ||
raw; | ||
constructor(ableton, raw) { | ||
super(ableton, "scene", raw.id); | ||
this.raw = raw; | ||
this.transformers = { | ||
clip_slots: (clip_slots) => clip_slots.map((c) => new clip_slot_1.ClipSlot(this.ableton, c)), | ||
}; | ||
_this.cachedProps = { | ||
this.cachedProps = { | ||
clip_slots: true, | ||
}; | ||
return _this; | ||
} | ||
@@ -76,11 +22,6 @@ /** | ||
*/ | ||
Scene.prototype.fire = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("fire")]; | ||
}); | ||
}); | ||
}; | ||
return Scene; | ||
}(_1.Namespace)); | ||
async fire() { | ||
return this.sendCommand("fire"); | ||
} | ||
} | ||
exports.Scene = Scene; |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
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; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.SongView = void 0; | ||
var _1 = require("."); | ||
var track_1 = require("./track"); | ||
var scene_1 = require("./scene"); | ||
var device_parameter_1 = require("./device-parameter"); | ||
var clip_slot_1 = require("./clip-slot"); | ||
var SongView = /** @class */ (function (_super) { | ||
__extends(SongView, _super); | ||
function SongView(ableton) { | ||
var _this = _super.call(this, ableton, "song-view") || this; | ||
_this.transformers = { | ||
selected_parameter: function (param) { return new device_parameter_1.DeviceParameter(ableton, param); }, | ||
selected_track: function (track) { return new track_1.Track(ableton, track); }, | ||
selected_scene: function (scene) { return new scene_1.Scene(ableton, scene); }, | ||
highlighted_clip_slot: function (slot) { return new clip_slot_1.ClipSlot(ableton, slot); }, | ||
const _1 = require("."); | ||
const track_1 = require("./track"); | ||
const scene_1 = require("./scene"); | ||
const device_parameter_1 = require("./device-parameter"); | ||
const clip_slot_1 = require("./clip-slot"); | ||
class SongView extends _1.Namespace { | ||
constructor(ableton) { | ||
super(ableton, "song-view"); | ||
this.transformers = { | ||
selected_parameter: (param) => new device_parameter_1.DeviceParameter(ableton, param), | ||
selected_track: (track) => new track_1.Track(ableton, track), | ||
selected_scene: (scene) => new scene_1.Scene(ableton, scene), | ||
highlighted_clip_slot: (slot) => new clip_slot_1.ClipSlot(ableton, slot), | ||
}; | ||
_this.cachedProps = { | ||
this.cachedProps = { | ||
selected_parameter: true, | ||
@@ -76,17 +24,11 @@ selected_track: true, | ||
}; | ||
return _this; | ||
} | ||
SongView.prototype.selectDevice = function (device) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.ableton.sendCommand({ | ||
ns: this.ns, | ||
name: "select_device", | ||
args: { device_id: device.raw.id }, | ||
})]; | ||
}); | ||
async selectDevice(device) { | ||
return this.ableton.sendCommand({ | ||
ns: this.ns, | ||
name: "select_device", | ||
args: { device_id: device.raw.id }, | ||
}); | ||
}; | ||
return SongView; | ||
}(_1.Namespace)); | ||
} | ||
} | ||
exports.SongView = SongView; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
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; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tests_1 = require("../util/tests"); | ||
var gettableProps = [ | ||
const tests_1 = require("../util/tests"); | ||
const gettableProps = [ | ||
"detail_clip", | ||
@@ -50,22 +14,8 @@ "draw_mode", | ||
]; | ||
describe("Song View", function () { | ||
it("should be able to read all properties without erroring", function () { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, tests_1.withAbleton(function (ab) { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, Promise.all(gettableProps.map(function (p) { return ab.song.view.get(p); }))]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); })]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
describe("Song View", () => { | ||
it("should be able to read all properties without erroring", async () => { | ||
await (0, tests_1.withAbleton)(async (ab) => { | ||
await Promise.all(gettableProps.map((p) => ab.song.view.get(p))); | ||
}); | ||
}); }); | ||
}); | ||
}); |
376
ns/song.js
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
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; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Song = exports.RecordingQuantization = exports.Quantization = exports.TimeFormat = void 0; | ||
var _1 = require("."); | ||
var track_1 = require("./track"); | ||
var cue_point_1 = require("./cue-point"); | ||
var song_view_1 = require("./song-view"); | ||
var scene_1 = require("./scene"); | ||
const _1 = require("."); | ||
const track_1 = require("./track"); | ||
const cue_point_1 = require("./cue-point"); | ||
const song_view_1 = require("./song-view"); | ||
const scene_1 = require("./scene"); | ||
var TimeFormat; | ||
@@ -68,3 +17,3 @@ (function (TimeFormat) { | ||
TimeFormat[TimeFormat["Smpte30Drop"] = 5] = "Smpte30Drop"; | ||
})(TimeFormat = exports.TimeFormat || (exports.TimeFormat = {})); | ||
})(TimeFormat || (exports.TimeFormat = TimeFormat = {})); | ||
var Quantization; | ||
@@ -86,3 +35,3 @@ (function (Quantization) { | ||
Quantization["q_thirtytwoth"] = "q_thirtytwoth"; | ||
})(Quantization = exports.Quantization || (exports.Quantization = {})); | ||
})(Quantization || (exports.Quantization = Quantization = {})); | ||
var RecordingQuantization; | ||
@@ -99,17 +48,15 @@ (function (RecordingQuantization) { | ||
RecordingQuantization["rec_q_thirtysecond"] = "rec_q_thirtysecond"; | ||
})(RecordingQuantization = exports.RecordingQuantization || (exports.RecordingQuantization = {})); | ||
var Song = /** @class */ (function (_super) { | ||
__extends(Song, _super); | ||
function Song(ableton) { | ||
var _this = _super.call(this, ableton, "song") || this; | ||
_this.view = new song_view_1.SongView(_this.ableton); | ||
_this.transformers = { | ||
cue_points: function (points) { return points.map(function (c) { return new cue_point_1.CuePoint(ableton, c); }); }, | ||
master_track: function (track) { return new track_1.Track(ableton, track); }, | ||
return_tracks: function (tracks) { return tracks.map(function (t) { return new track_1.Track(ableton, t); }); }, | ||
tracks: function (tracks) { return tracks.map(function (t) { return new track_1.Track(ableton, t); }); }, | ||
visible_tracks: function (tracks) { return tracks.map(function (t) { return new track_1.Track(ableton, t); }); }, | ||
scenes: function (scenes) { return scenes.map(function (s) { return new scene_1.Scene(ableton, s); }); }, | ||
})(RecordingQuantization || (exports.RecordingQuantization = RecordingQuantization = {})); | ||
class Song extends _1.Namespace { | ||
constructor(ableton) { | ||
super(ableton, "song"); | ||
this.transformers = { | ||
cue_points: (points) => points.map((c) => new cue_point_1.CuePoint(ableton, c)), | ||
master_track: (track) => new track_1.Track(ableton, track), | ||
return_tracks: (tracks) => tracks.map((t) => new track_1.Track(ableton, t)), | ||
tracks: (tracks) => tracks.map((t) => new track_1.Track(ableton, t)), | ||
visible_tracks: (tracks) => tracks.map((t) => new track_1.Track(ableton, t)), | ||
scenes: (scenes) => scenes.map((s) => new scene_1.Scene(ableton, s)), | ||
}; | ||
_this.cachedProps = { | ||
this.cachedProps = { | ||
cue_points: true, | ||
@@ -122,202 +69,89 @@ master_track: true, | ||
}; | ||
return _this; | ||
} | ||
Song.prototype.beginUndoStep = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("begin_undo_step")]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.continuePlaying = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("continue_playing")]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.createAudioTrack = function (index) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("create_audio_track", { index: index })]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.createMidiTrack = function (index) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("create_midi_track", { index: index })]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.createReturnTrack = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("create_return_track")]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.createScene = function (index) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("create_scene", [index])]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.deleteReturnTrack = function (index) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("delete_return_track", [index])]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.deleteScene = function (index) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("delete_scene", [index])]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.deleteTrack = function (index) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("delete_track", [index])]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.duplicateScene = function (index) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("duplicate_scene", [index])]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.duplicateTrack = function (index) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("duplicate_track", [index])]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.endUndoStep = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("end_undo_step")]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.getData = function (key) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCachedCommand("get_data", { key: key })]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.getCurrentSmpteSongTime = function (timeFormat) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("get_current_smpte_song_time", { timeFormat: timeFormat })]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.isCuePointSelected = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("is_cue_point_selected")]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.jumpBy = function (amount) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("jump_by", [amount])]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.jumpToNextCue = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("jump_to_next_cue")]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.jumpToPrevCue = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("jump_to_prev_cue")]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.playSelection = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("play_selection")]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.redo = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("redo")]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.scrubBy = function (amount) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("scrub_by", [amount])]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.setData = function (key, value) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("set_data", [key, value])]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.setOrDeleteCue = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("set_or_delete_cue")]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.startPlaying = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("start_playing")]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.stopAllClips = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("stop_all_clips")]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.stopPlaying = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("stop_playing")]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.tapTempo = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("tap_tempo")]; | ||
}); | ||
}); | ||
}; | ||
Song.prototype.undo = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, this.sendCommand("undo")]; | ||
}); | ||
}); | ||
}; | ||
return Song; | ||
}(_1.Namespace)); | ||
view = new song_view_1.SongView(this.ableton); | ||
async beginUndoStep() { | ||
return this.sendCommand("begin_undo_step"); | ||
} | ||
async continuePlaying() { | ||
return this.sendCommand("continue_playing"); | ||
} | ||
async createAudioTrack(index) { | ||
return this.sendCommand("create_audio_track", { index }); | ||
} | ||
async createMidiTrack(index) { | ||
return this.sendCommand("create_midi_track", { index }); | ||
} | ||
async createReturnTrack() { | ||
return this.sendCommand("create_return_track"); | ||
} | ||
async createScene(index) { | ||
return this.sendCommand("create_scene", [index]); | ||
} | ||
async deleteReturnTrack(index) { | ||
return this.sendCommand("delete_return_track", [index]); | ||
} | ||
async deleteScene(index) { | ||
return this.sendCommand("delete_scene", [index]); | ||
} | ||
async deleteTrack(index) { | ||
return this.sendCommand("delete_track", [index]); | ||
} | ||
async duplicateScene(index) { | ||
return this.sendCommand("duplicate_scene", [index]); | ||
} | ||
async duplicateTrack(index) { | ||
return this.sendCommand("duplicate_track", [index]); | ||
} | ||
async endUndoStep() { | ||
return this.sendCommand("end_undo_step"); | ||
} | ||
async getData(key) { | ||
return this.sendCachedCommand("get_data", { key }); | ||
} | ||
async getCurrentSmpteSongTime(timeFormat) { | ||
return this.sendCommand("get_current_smpte_song_time", { timeFormat }); | ||
} | ||
async isCuePointSelected() { | ||
return this.sendCommand("is_cue_point_selected"); | ||
} | ||
async jumpBy(amount) { | ||
return this.sendCommand("jump_by", [amount]); | ||
} | ||
async jumpToNextCue() { | ||
return this.sendCommand("jump_to_next_cue"); | ||
} | ||
async jumpToPrevCue() { | ||
return this.sendCommand("jump_to_prev_cue"); | ||
} | ||
async playSelection() { | ||
return this.sendCommand("play_selection"); | ||
} | ||
async redo() { | ||
return this.sendCommand("redo"); | ||
} | ||
async scrubBy(amount) { | ||
return this.sendCommand("scrub_by", [amount]); | ||
} | ||
async setData(key, value) { | ||
return this.sendCommand("set_data", [key, value]); | ||
} | ||
async setOrDeleteCue() { | ||
return this.sendCommand("set_or_delete_cue"); | ||
} | ||
async startPlaying() { | ||
return this.sendCommand("start_playing"); | ||
} | ||
async stopAllClips() { | ||
return this.sendCommand("stop_all_clips"); | ||
} | ||
async stopPlaying() { | ||
return this.sendCommand("stop_playing"); | ||
} | ||
async tapTempo() { | ||
return this.sendCommand("tap_tempo"); | ||
} | ||
async undo() { | ||
return this.sendCommand("undo"); | ||
} | ||
} | ||
exports.Song = Song; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
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; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tests_1 = require("../util/tests"); | ||
const tests_1 = require("../util/tests"); | ||
require("jest-extended"); | ||
var gettableProps = [ | ||
const gettableProps = [ | ||
"arrangement_overdub", | ||
@@ -88,80 +52,29 @@ "back_to_arranger", | ||
]; | ||
describe("Song", function () { | ||
it("should be able to read all properties without erroring", function () { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, tests_1.withAbleton(function (ab) { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, Promise.all(gettableProps.map(function (p) { return ab.song.get(p); }))]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); })]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
describe("Song", () => { | ||
it("should be able to read all properties without erroring", async () => { | ||
await (0, tests_1.withAbleton)(async (ab) => { | ||
await Promise.all(gettableProps.map((p) => ab.song.get(p))); | ||
}); | ||
}); }); | ||
it("should return the proper types for properties", function () { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, tests_1.withAbleton(function (ab) { return __awaiter(void 0, void 0, void 0, function () { | ||
var songTime, clipTriggerQuantization, isPlaying; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, ab.song.get("current_song_time")]; | ||
case 1: | ||
songTime = _a.sent(); | ||
expect(songTime).toBeNumber(); | ||
return [4 /*yield*/, ab.song.get("clip_trigger_quantization")]; | ||
case 2: | ||
clipTriggerQuantization = _a.sent(); | ||
expect(clipTriggerQuantization).toBeString(); | ||
return [4 /*yield*/, ab.song.get("is_playing")]; | ||
case 3: | ||
isPlaying = _a.sent(); | ||
expect(isPlaying).toBeBoolean(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); })]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
it("should return the proper types for properties", async () => { | ||
await (0, tests_1.withAbleton)(async (ab) => { | ||
const songTime = await ab.song.get("current_song_time"); | ||
expect(songTime).toBeNumber(); | ||
const clipTriggerQuantization = await ab.song.get("clip_trigger_quantization"); | ||
expect(clipTriggerQuantization).toBeString(); | ||
const isPlaying = await ab.song.get("is_playing"); | ||
expect(isPlaying).toBeBoolean(); | ||
}); | ||
}); }); | ||
it("should be able to write and read large objects from the project", function () { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, tests_1.withAbleton(function (ab) { return __awaiter(void 0, void 0, void 0, function () { | ||
var largeArray, i, received; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
largeArray = []; | ||
for (i = 0; i < 100000; i++) { | ||
largeArray.push(i); | ||
} | ||
return [4 /*yield*/, ab.song.setData("abletonjs_test", largeArray)]; | ||
case 1: | ||
_a.sent(); | ||
return [4 /*yield*/, ab.song.getData("abletonjs_test")]; | ||
case 2: | ||
received = _a.sent(); | ||
expect(received).toEqual(largeArray); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); })]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
}); | ||
it("should be able to write and read large objects from the project", async () => { | ||
await (0, tests_1.withAbleton)(async (ab) => { | ||
const largeArray = []; | ||
for (let i = 0; i < 100000; i++) { | ||
largeArray.push(i); | ||
} | ||
await ab.song.setData("abletonjs_test", largeArray); | ||
const received = await ab.song.getData("abletonjs_test"); | ||
expect(received).toEqual(largeArray); | ||
}); | ||
}); }); | ||
}); | ||
}); |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Track = exports.RoutingCategory = exports.RoutingLayout = void 0; | ||
var _1 = require("."); | ||
var device_1 = require("./device"); | ||
var clip_slot_1 = require("./clip-slot"); | ||
var mixer_device_1 = require("./mixer-device"); | ||
var clip_1 = require("./clip"); | ||
var color_1 = require("../util/color"); | ||
const _1 = require("."); | ||
const device_1 = require("./device"); | ||
const clip_slot_1 = require("./clip-slot"); | ||
const mixer_device_1 = require("./mixer-device"); | ||
const clip_1 = require("./clip"); | ||
const color_1 = require("../util/color"); | ||
var RoutingLayout; | ||
@@ -29,3 +14,3 @@ (function (RoutingLayout) { | ||
RoutingLayout[RoutingLayout["Stereo"] = 2] = "Stereo"; | ||
})(RoutingLayout = exports.RoutingLayout || (exports.RoutingLayout = {})); | ||
})(RoutingLayout || (exports.RoutingLayout = RoutingLayout = {})); | ||
var RoutingCategory; | ||
@@ -41,20 +26,16 @@ (function (RoutingCategory) { | ||
RoutingCategory[RoutingCategory["Invalid"] = 7] = "Invalid"; | ||
})(RoutingCategory = exports.RoutingCategory || (exports.RoutingCategory = {})); | ||
var Track = /** @class */ (function (_super) { | ||
__extends(Track, _super); | ||
function Track(ableton, raw) { | ||
var _this = _super.call(this, ableton, "track", raw.id) || this; | ||
_this.raw = raw; | ||
_this.transformers = { | ||
arrangement_clips: function (clips) { | ||
return clips.map(function (clip) { return new clip_1.Clip(ableton, clip); }); | ||
}, | ||
color: function (c) { return new color_1.Color(c); }, | ||
devices: function (devices) { return devices.map(function (d) { return new device_1.Device(ableton, d); }); }, | ||
clip_slots: function (clip_slots) { | ||
return clip_slots.map(function (c) { return new clip_slot_1.ClipSlot(ableton, c); }); | ||
}, | ||
mixer_device: function (mixer_device) { return new mixer_device_1.MixerDevice(ableton, mixer_device); }, | ||
})(RoutingCategory || (exports.RoutingCategory = RoutingCategory = {})); | ||
class Track extends _1.Namespace { | ||
raw; | ||
constructor(ableton, raw) { | ||
super(ableton, "track", raw.id); | ||
this.raw = raw; | ||
this.transformers = { | ||
arrangement_clips: (clips) => clips.map((clip) => new clip_1.Clip(ableton, clip)), | ||
color: (c) => new color_1.Color(c), | ||
devices: (devices) => devices.map((d) => new device_1.Device(ableton, d)), | ||
clip_slots: (clip_slots) => clip_slots.map((c) => new clip_slot_1.ClipSlot(ableton, c)), | ||
mixer_device: (mixer_device) => new mixer_device_1.MixerDevice(ableton, mixer_device), | ||
}; | ||
_this.cachedProps = { | ||
this.cachedProps = { | ||
arrangement_clips: true, | ||
@@ -64,3 +45,2 @@ devices: true, | ||
}; | ||
return _this; | ||
} | ||
@@ -71,3 +51,3 @@ /** | ||
*/ | ||
Track.prototype.duplicateClipToArrangement = function (clipOrId, time) { | ||
duplicateClipToArrangement(clipOrId, time) { | ||
return this.sendCommand("duplicate_clip_to_arrangement", { | ||
@@ -77,5 +57,4 @@ clip_id: typeof clipOrId === "string" ? clipOrId : clipOrId.raw.id, | ||
}); | ||
}; | ||
return Track; | ||
}(_1.Namespace)); | ||
} | ||
} | ||
exports.Track = Track; |
{ | ||
"name": "ableton-js", | ||
"version": "3.1.9", | ||
"version": "3.2.0", | ||
"description": "Control Ableton Live from Node", | ||
@@ -35,3 +35,3 @@ "main": "index.js", | ||
"@types/lodash": "^4.14.194", | ||
"@types/node": "^15.6.1", | ||
"@types/node": "^20.3.0", | ||
"@types/node-uuid": "^0.0.28", | ||
@@ -45,5 +45,5 @@ "@types/semver": "^7.3.6", | ||
"p-all": "^3", | ||
"ts-jest": "^27.0.1", | ||
"ts-node": "^10.0.0", | ||
"typescript": "^4.3.2" | ||
"ts-jest": "^29.1.0", | ||
"ts-node": "^10.9.1", | ||
"typescript": "^5.1.3" | ||
}, | ||
@@ -50,0 +50,0 @@ "dependencies": { |
@@ -26,8 +26,5 @@ # Ableton.js | ||
Ableton's Remote Scripts folder and rename it to `AbletonJS`. The MIDI Remote | ||
Scripts folder is usually located at: | ||
Scripts folder is usually located at | ||
`~/Music/Ableton/User Library/Remote Scripts` | ||
- **Windows:** {path to Ableton}\Resources\MIDI\Remote Scripts | ||
- **macOS:** /Applications/Ableton Live {version}/Contents/App-Resources/MIDI | ||
Remote Scripts | ||
After starting Ableton Live, add the script to your list of control surfaces: | ||
@@ -34,0 +31,0 @@ |
import type LruCache from "lru-cache"; | ||
export declare type CachedResponse = { | ||
export type CachedResponse = { | ||
__cached: true; | ||
}; | ||
export declare type CacheResponse = CachedResponse | { | ||
export type CacheResponse = CachedResponse | { | ||
data: any; | ||
@@ -14,2 +14,2 @@ etag: string; | ||
} | ||
export declare type Cache = LruCache<string, CacheObject>; | ||
export type Cache = LruCache<string, CacheObject>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isCached = void 0; | ||
var isCached = function (obj) { | ||
return obj && "__cached" in obj; | ||
}; | ||
const isCached = (obj) => obj && "__cached" in obj; | ||
exports.isCached = isCached; |
@@ -5,4 +5,5 @@ "use strict"; | ||
/** Represents a color in Ableton */ | ||
var Color = /** @class */ (function () { | ||
function Color(color) { | ||
class Color { | ||
color; | ||
constructor(color) { | ||
if (typeof color === "number") { | ||
@@ -18,35 +19,22 @@ this.color = color.toString(16).padStart(6, "0"); | ||
} | ||
Object.defineProperty(Color.prototype, "hex", { | ||
get: function () { | ||
return "#" + this.color; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
Object.defineProperty(Color.prototype, "rgb", { | ||
get: function () { | ||
return { | ||
r: parseInt(this.color.substr(0, 2), 16), | ||
g: parseInt(this.color.substr(2, 2), 16), | ||
b: parseInt(this.color.substr(4, 2), 16), | ||
}; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
Object.defineProperty(Color.prototype, "numberRepresentation", { | ||
get: function () { | ||
return parseInt(this.color, 16); | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
Color.prototype.toString = function () { | ||
get hex() { | ||
return `#${this.color}`; | ||
} | ||
get rgb() { | ||
return { | ||
r: parseInt(this.color.substr(0, 2), 16), | ||
g: parseInt(this.color.substr(2, 2), 16), | ||
b: parseInt(this.color.substr(4, 2), 16), | ||
}; | ||
} | ||
get numberRepresentation() { | ||
return parseInt(this.color, 16); | ||
} | ||
toString() { | ||
return this.hex; | ||
}; | ||
Color.prototype.toJSON = function () { | ||
} | ||
toJSON() { | ||
return this.numberRepresentation; | ||
}; | ||
return Color; | ||
}()); | ||
} | ||
} | ||
exports.Color = Color; |
@@ -1,2 +0,2 @@ | ||
export declare type NoteTuple = [ | ||
export type NoteTuple = [ | ||
pitch: number, | ||
@@ -3,0 +3,0 @@ time: number, |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.noteToTuple = exports.tupleToNote = void 0; | ||
var tupleToNote = function (tuple) { return ({ | ||
const tupleToNote = (tuple) => ({ | ||
pitch: tuple[0], | ||
@@ -10,5 +10,5 @@ time: tuple[1], | ||
muted: tuple[4], | ||
}); }; | ||
}); | ||
exports.tupleToNote = tupleToNote; | ||
var noteToTuple = function (note) { return [ | ||
const noteToTuple = (note) => [ | ||
note.pitch, | ||
@@ -19,3 +19,3 @@ note.time, | ||
note.muted, | ||
]; }; | ||
]; | ||
exports.noteToTuple = noteToTuple; |
@@ -7,7 +7,7 @@ "use strict"; | ||
exports.getPackageVersion = void 0; | ||
var fs_1 = __importDefault(require("fs")); | ||
var path_1 = __importDefault(require("path")); | ||
var getPackageVersion = function () { | ||
var parentPath = path_1.default.join(__dirname, "..", "package.json"); | ||
var parent2Path = path_1.default.join(__dirname, "..", "..", "package.json"); | ||
const fs_1 = __importDefault(require("fs")); | ||
const path_1 = __importDefault(require("path")); | ||
const getPackageVersion = () => { | ||
const parentPath = path_1.default.join(__dirname, "..", "package.json"); | ||
const parent2Path = path_1.default.join(__dirname, "..", "..", "package.json"); | ||
if (fs_1.default.existsSync(parentPath)) { | ||
@@ -14,0 +14,0 @@ return require(parentPath).version; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var package_version_1 = require("./package-version"); | ||
var semver_1 = require("semver"); | ||
describe("Package Version", function () { | ||
it("should get a valid package version without erroring", function () { | ||
var version = package_version_1.getPackageVersion(); | ||
expect(semver_1.valid(version)).toBeTruthy(); | ||
const package_version_1 = require("./package-version"); | ||
const semver_1 = require("semver"); | ||
describe("Package Version", () => { | ||
it("should get a valid package version without erroring", () => { | ||
const version = (0, package_version_1.getPackageVersion)(); | ||
expect((0, semver_1.valid)(version)).toBeTruthy(); | ||
}); | ||
}); |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
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; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.withAbleton = void 0; | ||
const __1 = require(".."); | ||
const withAbleton = async (callback) => { | ||
const ab = new __1.Ableton(); | ||
ab.on("error", console.error); | ||
await ab.start(2000); | ||
try { | ||
await callback(ab); | ||
} | ||
finally { | ||
await ab.close(); | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.withAbleton = void 0; | ||
var __1 = require(".."); | ||
var withAbleton = function (callback) { return __awaiter(void 0, void 0, void 0, function () { | ||
var ab; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
ab = new __1.Ableton(); | ||
ab.on("error", console.error); | ||
return [4 /*yield*/, ab.start(2000)]; | ||
case 1: | ||
_a.sent(); | ||
_a.label = 2; | ||
case 2: | ||
_a.trys.push([2, , 4, 6]); | ||
return [4 /*yield*/, callback(ab)]; | ||
case 3: | ||
_a.sent(); | ||
return [3 /*break*/, 6]; | ||
case 4: return [4 /*yield*/, ab.close()]; | ||
case 5: | ||
_a.sent(); | ||
return [7 /*endfinally*/]; | ||
case 6: return [2 /*return*/]; | ||
} | ||
}); | ||
}); }; | ||
exports.withAbleton = withAbleton; |
Sorry, the diff of this file is not supported yet
176430
3660
243