Merging zn
This commit is contained in:
@ -62,6 +62,8 @@ To build a standalone browser application using [Tauri](https://tauri.app/), you
|
|||||||
- [ ] Give more information the local context of execution of every script
|
- [ ] Give more information the local context of execution of every script
|
||||||
- print/display the internal iterator used in each script
|
- print/display the internal iterator used in each script
|
||||||
- animate code to show which line is currently being executed
|
- animate code to show which line is currently being executed
|
||||||
|
- [ ] More rhythmic generators
|
||||||
|
- [ ] Rendering static files (MIDI, MOD, etc...)
|
||||||
|
|
||||||
## Scheduler
|
## Scheduler
|
||||||
|
|
||||||
|
|||||||
311
src/API.ts
311
src/API.ts
@ -1,14 +1,16 @@
|
|||||||
import { Editor } from "./main";
|
import { Editor } from "./main";
|
||||||
import { scale } from './Scales';
|
import { scale } from "./Scales";
|
||||||
import { tryEvaluate } from "./Evaluator";
|
import { tryEvaluate } from "./Evaluator";
|
||||||
import { MidiConnection } from "./IO/MidiConnection";
|
import { MidiConnection } from "./IO/MidiConnection";
|
||||||
import { DrunkWalk } from './Utils/Drunk';
|
import { DrunkWalk } from "./Utils/Drunk";
|
||||||
import { Pitch, Chord, Rest, Event, Start, cachedStart } from "zifferjs";
|
import { Pitch, Chord, Rest, Event, Start, cachedStart } from "zifferjs";
|
||||||
import {
|
import {
|
||||||
superdough, samples,
|
superdough,
|
||||||
|
samples,
|
||||||
initAudioOnFirstClick,
|
initAudioOnFirstClick,
|
||||||
registerSynthSounds
|
registerSynthSounds,
|
||||||
} from 'superdough';
|
// @ts-ignore
|
||||||
|
} from "superdough";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We are overriding the includes method which is rather
|
* We are overriding the includes method which is rather
|
||||||
@ -19,20 +21,17 @@ declare global {
|
|||||||
in(value: T): boolean;
|
in(value: T): boolean;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Array.prototype.in = function<T>(this: T[], value: T): boolean {
|
Array.prototype.in = function <T>(this: T[], value: T): boolean {
|
||||||
return this.includes(value);
|
return this.includes(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Promise.all([
|
||||||
const init = Promise.all([
|
|
||||||
initAudioOnFirstClick(),
|
initAudioOnFirstClick(),
|
||||||
samples('github:tidalcycles/Dirt-Samples/master'),
|
samples("github:tidalcycles/Dirt-Samples/master"),
|
||||||
samples('github:kindohm/expedition/tree/master/samples'),
|
|
||||||
registerSynthSounds(),
|
registerSynthSounds(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export class UserAPI {
|
export class UserAPI {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The UserAPI class is the interface between the user's code and the backend. It provides
|
* The UserAPI class is the interface between the user's code and the backend. It provides
|
||||||
* access to the AudioContext, to the MIDI Interface, to internal variables, mouse position,
|
* access to the AudioContext, to the MIDI Interface, to internal variables, mouse position,
|
||||||
@ -40,14 +39,14 @@ export class UserAPI {
|
|||||||
* function destined to the user should be placed here.
|
* function destined to the user should be placed here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private variables: { [key: string]: any } = {}
|
private variables: { [key: string]: any } = {};
|
||||||
private iterators: { [key: string]: any } = {}
|
private iterators: { [key: string]: any } = {};
|
||||||
private _drunk: DrunkWalk = new DrunkWalk(-100, 100, false);
|
private _drunk: DrunkWalk = new DrunkWalk(-100, 100, false);
|
||||||
|
|
||||||
MidiConnection: MidiConnection = new MidiConnection()
|
MidiConnection: MidiConnection = new MidiConnection();
|
||||||
load: samples
|
load: samples;
|
||||||
|
|
||||||
constructor (public app: Editor) {
|
constructor(public app: Editor) {
|
||||||
this.load = samples("github:tidalcycles/Dirt-Samples/master");
|
this.load = samples("github:tidalcycles/Dirt-Samples/master");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +58,7 @@ export class UserAPI {
|
|||||||
/**
|
/**
|
||||||
* @returns The current time for the AudioContext
|
* @returns The current time for the AudioContext
|
||||||
*/
|
*/
|
||||||
return this.app.audioContext.currentTime
|
return this.app.audioContext.currentTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
@ -70,23 +69,23 @@ export class UserAPI {
|
|||||||
/**
|
/**
|
||||||
* @returns The current x position of the mouse
|
* @returns The current x position of the mouse
|
||||||
*/
|
*/
|
||||||
return this.app._mouseX
|
return this.app._mouseX;
|
||||||
}
|
}
|
||||||
|
|
||||||
get mouseY(): number {
|
get mouseY(): number {
|
||||||
/**
|
/**
|
||||||
* @returns The current y position of the mouse
|
* @returns The current y position of the mouse
|
||||||
*/
|
*/
|
||||||
return this.app._mouseY
|
return this.app._mouseY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
// Utility functions
|
// Utility functions
|
||||||
// =============================================================
|
// =============================================================
|
||||||
|
|
||||||
log = console.log
|
log = console.log;
|
||||||
|
|
||||||
scale = scale
|
scale = scale;
|
||||||
|
|
||||||
rate(rate: number): void {
|
rate(rate: number): void {
|
||||||
rate = rate;
|
rate = rate;
|
||||||
@ -102,14 +101,14 @@ export class UserAPI {
|
|||||||
* @param args - The scripts to evaluate
|
* @param args - The scripts to evaluate
|
||||||
* @returns The result of the evaluation
|
* @returns The result of the evaluation
|
||||||
*/
|
*/
|
||||||
args.forEach(arg => {
|
args.forEach((arg) => {
|
||||||
tryEvaluate(
|
tryEvaluate(
|
||||||
this.app,
|
this.app,
|
||||||
this.app.universes[this.app.selected_universe].locals[arg],
|
this.app.universes[this.app.selected_universe].locals[arg]
|
||||||
)
|
);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
s = this.script
|
s = this.script;
|
||||||
|
|
||||||
clearscript(script: number): void {
|
clearscript(script: number): void {
|
||||||
/**
|
/**
|
||||||
@ -118,10 +117,12 @@ export class UserAPI {
|
|||||||
* @param script - The script to clear
|
* @param script - The script to clear
|
||||||
*/
|
*/
|
||||||
this.app.universes[this.app.selected_universe].locals[script] = {
|
this.app.universes[this.app.selected_universe].locals[script] = {
|
||||||
candidate: '', committed: '', evaluations: 0
|
candidate: "",
|
||||||
|
committed: "",
|
||||||
|
evaluations: 0,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
cs = this.clearscript;
|
||||||
cs = this.clearscript
|
|
||||||
|
|
||||||
copyscript(from: number, to: number): void {
|
copyscript(from: number, to: number): void {
|
||||||
/**
|
/**
|
||||||
@ -131,9 +132,9 @@ export class UserAPI {
|
|||||||
* @param to - The script to copy to
|
* @param to - The script to copy to
|
||||||
*/
|
*/
|
||||||
this.app.universes[this.app.selected_universe].locals[to] =
|
this.app.universes[this.app.selected_universe].locals[to] =
|
||||||
this.app.universes[this.app.selected_universe].locals[from]
|
this.app.universes[this.app.selected_universe].locals[from];
|
||||||
}
|
}
|
||||||
cps = this.copyscript
|
cps = this.copyscript;
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
// MIDI related functions
|
// MIDI related functions
|
||||||
@ -156,13 +157,13 @@ export class UserAPI {
|
|||||||
* @param outputName - The name of the MIDI output to switch to
|
* @param outputName - The name of the MIDI output to switch to
|
||||||
*/
|
*/
|
||||||
if (!outputName) {
|
if (!outputName) {
|
||||||
console.log(this.MidiConnection.getCurrentMidiPort())
|
console.log(this.MidiConnection.getCurrentMidiPort());
|
||||||
} else {
|
} else {
|
||||||
this.MidiConnection.switchMidiOutput(outputName)
|
this.MidiConnection.switchMidiOutput(outputName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public note(note: number, options: {[key: string]: number} = {}): void {
|
public note(note: number, options: { [key: string]: number } = {}): void {
|
||||||
/**
|
/**
|
||||||
* Sends a MIDI note to the current MIDI output.
|
* Sends a MIDI note to the current MIDI output.
|
||||||
*
|
*
|
||||||
@ -172,12 +173,13 @@ export class UserAPI {
|
|||||||
*/
|
*/
|
||||||
const channel = options.channel ? options.channel : 0;
|
const channel = options.channel ? options.channel : 0;
|
||||||
const velocity = options.velocity ? options.velocity : 100;
|
const velocity = options.velocity ? options.velocity : 100;
|
||||||
const duration = options.duration ? options.duration: 0.5;
|
const duration = options.duration ? options.duration : 0.5;
|
||||||
this.MidiConnection.sendMidiNote(note, channel, velocity, duration)
|
this.MidiConnection.sendMidiNote(note, channel, velocity, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public zn(input: string, options: {[key: string]: string|number} = {}): Event {
|
public zn(input: string,
|
||||||
let event = cachedStart(input, options);
|
options: {[key: string]: string|number} = {}): Event {
|
||||||
|
const event = cachedStart(input, options);
|
||||||
if(event instanceof Start) {
|
if(event instanceof Start) {
|
||||||
// do nothing for now ...
|
// do nothing for now ...
|
||||||
} else {
|
} else {
|
||||||
@ -210,7 +212,7 @@ export class UserAPI {
|
|||||||
*
|
*
|
||||||
* @param data - The sysex data to send
|
* @param data - The sysex data to send
|
||||||
*/
|
*/
|
||||||
this.MidiConnection.sendSysExMessage(data)
|
this.MidiConnection.sendSysExMessage(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public pitch_bend(value: number, channel: number): void {
|
public pitch_bend(value: number, channel: number): void {
|
||||||
@ -222,7 +224,7 @@ export class UserAPI {
|
|||||||
*
|
*
|
||||||
* @returns The value of the pitch bend
|
* @returns The value of the pitch bend
|
||||||
*/
|
*/
|
||||||
this.MidiConnection.sendPitchBend(value, channel)
|
this.MidiConnection.sendPitchBend(value, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public program_change(program: number, channel: number): void {
|
public program_change(program: number, channel: number): void {
|
||||||
@ -232,14 +234,14 @@ export class UserAPI {
|
|||||||
* @param program - The MIDI program to send
|
* @param program - The MIDI program to send
|
||||||
* @param channel - The MIDI channel to send the program change on
|
* @param channel - The MIDI channel to send the program change on
|
||||||
*/
|
*/
|
||||||
this.MidiConnection.sendProgramChange(program, channel)
|
this.MidiConnection.sendProgramChange(program, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public midi_clock(): void {
|
public midi_clock(): void {
|
||||||
/**
|
/**
|
||||||
* Sends a MIDI clock to the current MIDI output.
|
* Sends a MIDI clock to the current MIDI output.
|
||||||
*/
|
*/
|
||||||
this.MidiConnection.sendMidiClock()
|
this.MidiConnection.sendMidiClock();
|
||||||
}
|
}
|
||||||
|
|
||||||
public cc(control: number, value: number): void {
|
public cc(control: number, value: number): void {
|
||||||
@ -249,14 +251,14 @@ export class UserAPI {
|
|||||||
* @param control - The MIDI control to send
|
* @param control - The MIDI control to send
|
||||||
* @param value - The value of the control
|
* @param value - The value of the control
|
||||||
*/
|
*/
|
||||||
this.MidiConnection.sendMidiControlChange(control, value)
|
this.MidiConnection.sendMidiControlChange(control, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public midi_panic(): void {
|
public midi_panic(): void {
|
||||||
/**
|
/**
|
||||||
* Sends a MIDI panic message to the current MIDI output.
|
* Sends a MIDI panic message to the current MIDI output.
|
||||||
*/
|
*/
|
||||||
this.MidiConnection.panic()
|
this.MidiConnection.panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
@ -278,7 +280,7 @@ export class UserAPI {
|
|||||||
this.iterators[name] = {
|
this.iterators[name] = {
|
||||||
value: 0,
|
value: 0,
|
||||||
step: step ?? 1,
|
step: step ?? 1,
|
||||||
limit
|
limit,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// Check if limit has changed
|
// Check if limit has changed
|
||||||
@ -298,8 +300,10 @@ export class UserAPI {
|
|||||||
this.iterators[name].value += this.iterators[name].step;
|
this.iterators[name].value += this.iterators[name].step;
|
||||||
|
|
||||||
// Check for limit overshoot
|
// Check for limit overshoot
|
||||||
if (this.iterators[name].limit !== undefined &&
|
if (
|
||||||
this.iterators[name].value > this.iterators[name].limit) {
|
this.iterators[name].limit !== undefined &&
|
||||||
|
this.iterators[name].value > this.iterators[name].limit
|
||||||
|
) {
|
||||||
this.iterators[name].value = 0;
|
this.iterators[name].value = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -307,7 +311,7 @@ export class UserAPI {
|
|||||||
// Return current iterator value
|
// Return current iterator value
|
||||||
return this.iterators[name].value;
|
return this.iterators[name].value;
|
||||||
}
|
}
|
||||||
$ = this.iterator
|
$ = this.iterator;
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
// Drunk mechanism
|
// Drunk mechanism
|
||||||
@ -373,14 +377,14 @@ export class UserAPI {
|
|||||||
* @param b - [optional] The value to set the variable to
|
* @param b - [optional] The value to set the variable to
|
||||||
* @returns The value of the variable
|
* @returns The value of the variable
|
||||||
*/
|
*/
|
||||||
if (typeof a === 'string' && b === undefined) {
|
if (typeof a === "string" && b === undefined) {
|
||||||
return this.variables[a]
|
return this.variables[a];
|
||||||
} else {
|
} else {
|
||||||
this.variables[a] = b
|
this.variables[a] = b;
|
||||||
return this.variables[a]
|
return this.variables[a];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v = this.variable
|
v = this.variable;
|
||||||
|
|
||||||
public delete_variable(name: string): void {
|
public delete_variable(name: string): void {
|
||||||
/**
|
/**
|
||||||
@ -388,9 +392,9 @@ export class UserAPI {
|
|||||||
*
|
*
|
||||||
* @param name - The name of the variable to delete
|
* @param name - The name of the variable to delete
|
||||||
*/
|
*/
|
||||||
delete this.variables[name]
|
delete this.variables[name];
|
||||||
}
|
}
|
||||||
dv = this.delete_variable
|
dv = this.delete_variable;
|
||||||
|
|
||||||
public clear_variables(): void {
|
public clear_variables(): void {
|
||||||
/**
|
/**
|
||||||
@ -400,9 +404,9 @@ export class UserAPI {
|
|||||||
* This function will delete all variables without warning.
|
* This function will delete all variables without warning.
|
||||||
* Use with caution.
|
* Use with caution.
|
||||||
*/
|
*/
|
||||||
this.variables = {}
|
this.variables = {};
|
||||||
}
|
}
|
||||||
cv = this.clear_variables
|
cv = this.clear_variables;
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
// Small algorithmic functions
|
// Small algorithmic functions
|
||||||
@ -414,7 +418,7 @@ export class UserAPI {
|
|||||||
*
|
*
|
||||||
* @param array - The array of values to pick from
|
* @param array - The array of values to pick from
|
||||||
*/
|
*/
|
||||||
return array[Math.floor(Math.random() * array.length)]
|
return array[Math.floor(Math.random() * array.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
seqbeat<T>(...array: T[]): T {
|
seqbeat<T>(...array: T[]): T {
|
||||||
@ -423,7 +427,7 @@ export class UserAPI {
|
|||||||
*
|
*
|
||||||
* @param array - The array of values to pick from
|
* @param array - The array of values to pick from
|
||||||
*/
|
*/
|
||||||
return array[this.app.clock.time_position.beat % array.length]
|
return array[this.ebeat % array.length];
|
||||||
}
|
}
|
||||||
|
|
||||||
mel<T>(iterator: number, array: T[]): T {
|
mel<T>(iterator: number, array: T[]): T {
|
||||||
@ -433,7 +437,7 @@ export class UserAPI {
|
|||||||
* @param iterator - The name of the iterator
|
* @param iterator - The name of the iterator
|
||||||
* @param array - The array of values to pick from
|
* @param array - The array of values to pick from
|
||||||
*/
|
*/
|
||||||
return array[iterator % array.length]
|
return array[iterator % array.length];
|
||||||
}
|
}
|
||||||
|
|
||||||
seqbar<T>(...array: T[]): T {
|
seqbar<T>(...array: T[]): T {
|
||||||
@ -442,7 +446,7 @@ export class UserAPI {
|
|||||||
*
|
*
|
||||||
* @param array - The array of values to pick from
|
* @param array - The array of values to pick from
|
||||||
*/
|
*/
|
||||||
return array[this.app.clock.time_position.bar % array.length]
|
return array[(this.app.clock.time_position.bar + 1) % array.length];
|
||||||
}
|
}
|
||||||
|
|
||||||
seqpulse<T>(...array: T[]): T {
|
seqpulse<T>(...array: T[]): T {
|
||||||
@ -451,7 +455,7 @@ export class UserAPI {
|
|||||||
*
|
*
|
||||||
* @param array - The array of values to pick from
|
* @param array - The array of values to pick from
|
||||||
*/
|
*/
|
||||||
return array[this.app.clock.time_position.pulse % array.length]
|
return array[this.app.clock.time_position.pulse % array.length];
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
@ -466,7 +470,7 @@ export class UserAPI {
|
|||||||
* @param max - The maximum value of the random number
|
* @param max - The maximum value of the random number
|
||||||
* @returns A random integer between min and max
|
* @returns A random integer between min and max
|
||||||
*/
|
*/
|
||||||
return Math.floor(Math.random() * (max - min + 1)) + min
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
}
|
}
|
||||||
|
|
||||||
rand(min: number, max: number): number {
|
rand(min: number, max: number): number {
|
||||||
@ -477,9 +481,10 @@ export class UserAPI {
|
|||||||
* @param max - The maximum value of the random number
|
* @param max - The maximum value of the random number
|
||||||
* @returns A random float between min and max
|
* @returns A random float between min and max
|
||||||
*/
|
*/
|
||||||
return Math.random() * (max - min) + min
|
return Math.random() * (max - min) + min;
|
||||||
}
|
}
|
||||||
rI = this.randI; r = this.rand
|
rI = this.randI;
|
||||||
|
r = this.rand;
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
// Quantification functions
|
// Quantification functions
|
||||||
@ -493,14 +498,18 @@ export class UserAPI {
|
|||||||
* @param quantization - The array of values to quantize to
|
* @param quantization - The array of values to quantize to
|
||||||
* @returns The closest value in the array to the given value
|
* @returns The closest value in the array to the given value
|
||||||
*/
|
*/
|
||||||
if (quantization.length === 0) { return value }
|
if (quantization.length === 0) {
|
||||||
let closest = quantization[0]
|
return value;
|
||||||
quantization.forEach(q => {
|
|
||||||
if (Math.abs(q - value) < Math.abs(closest - value)) { closest = q }
|
|
||||||
})
|
|
||||||
return closest
|
|
||||||
}
|
}
|
||||||
quant = this.quantize
|
let closest = quantization[0];
|
||||||
|
quantization.forEach((q) => {
|
||||||
|
if (Math.abs(q - value) < Math.abs(closest - value)) {
|
||||||
|
closest = q;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return closest;
|
||||||
|
}
|
||||||
|
quant = this.quantize;
|
||||||
|
|
||||||
public clamp(value: number, min: number, max: number): number {
|
public clamp(value: number, min: number, max: number): number {
|
||||||
/**
|
/**
|
||||||
@ -511,9 +520,9 @@ export class UserAPI {
|
|||||||
* @param max - The maximum value of the clamped value
|
* @param max - The maximum value of the clamped value
|
||||||
* @returns A value clamped between min and max
|
* @returns A value clamped between min and max
|
||||||
*/
|
*/
|
||||||
return Math.min(Math.max(value, min), max)
|
return Math.min(Math.max(value, min), max);
|
||||||
}
|
}
|
||||||
cmp = this.clamp
|
cmp = this.clamp;
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
// Transport functions
|
// Transport functions
|
||||||
@ -526,15 +535,13 @@ export class UserAPI {
|
|||||||
* @param bpm - [optional] The bpm to set
|
* @param bpm - [optional] The bpm to set
|
||||||
* @returns The current bpm
|
* @returns The current bpm
|
||||||
*/
|
*/
|
||||||
if (n === undefined)
|
if (n === undefined) return this.app.clock.bpm;
|
||||||
return this.app.clock.bpm
|
|
||||||
|
|
||||||
if (n < 1 || n > 500)
|
if (n < 1 || n > 500) console.log(`Setting bpm to ${n}`);
|
||||||
console.log(`Setting bpm to ${n}`)
|
this.app.clock.bpm = n;
|
||||||
this.app.clock.bpm = n
|
return n;
|
||||||
return n
|
|
||||||
}
|
}
|
||||||
tempo = this.bpm
|
tempo = this.bpm;
|
||||||
|
|
||||||
time_signature(numerator: number, denominator: number): void {
|
time_signature(numerator: number, denominator: number): void {
|
||||||
/**
|
/**
|
||||||
@ -544,20 +551,20 @@ export class UserAPI {
|
|||||||
* @param denominator - The denominator of the time signature
|
* @param denominator - The denominator of the time signature
|
||||||
* @returns The current time signature
|
* @returns The current time signature
|
||||||
*/
|
*/
|
||||||
this.app.clock.time_signature = [numerator, denominator]
|
this.app.clock.time_signature = [numerator, denominator];
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
// Probability functions
|
// Probability functions
|
||||||
// =============================================================
|
// =============================================================
|
||||||
|
|
||||||
public almostNever():boolean {
|
public almostNever(): boolean {
|
||||||
/**
|
/**
|
||||||
* Returns true 10% of the time.
|
* Returns true 10% of the time.
|
||||||
*
|
*
|
||||||
* @returns True 10% of the time
|
* @returns True 10% of the time
|
||||||
*/
|
*/
|
||||||
return Math.random() > 0.9
|
return Math.random() > 0.9;
|
||||||
}
|
}
|
||||||
|
|
||||||
public sometimes(): boolean {
|
public sometimes(): boolean {
|
||||||
@ -566,16 +573,16 @@ export class UserAPI {
|
|||||||
*
|
*
|
||||||
* @returns True 50% of the time
|
* @returns True 50% of the time
|
||||||
*/
|
*/
|
||||||
return Math.random() > 0.5
|
return Math.random() > 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
public rarely():boolean {
|
public rarely(): boolean {
|
||||||
/**
|
/**
|
||||||
* Returns true 25% of the time.
|
* Returns true 25% of the time.
|
||||||
*
|
*
|
||||||
* @returns True 25% of the time
|
* @returns True 25% of the time
|
||||||
*/
|
*/
|
||||||
return Math.random() > 0.75
|
return Math.random() > 0.75;
|
||||||
}
|
}
|
||||||
|
|
||||||
public often(): boolean {
|
public often(): boolean {
|
||||||
@ -584,26 +591,26 @@ export class UserAPI {
|
|||||||
*
|
*
|
||||||
* @returns True 75% of the time
|
* @returns True 75% of the time
|
||||||
*/
|
*/
|
||||||
return Math.random() > 0.25
|
return Math.random() > 0.25;
|
||||||
}
|
}
|
||||||
|
|
||||||
public almostAlways():boolean {
|
public almostAlways(): boolean {
|
||||||
/**
|
/**
|
||||||
* Returns true 90% of the time.
|
* Returns true 90% of the time.
|
||||||
*
|
*
|
||||||
* @returns True 90% of the time
|
* @returns True 90% of the time
|
||||||
*/
|
*/
|
||||||
return Math.random() > 0.1
|
return Math.random() > 0.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public dice(sides: number):number {
|
public dice(sides: number): number {
|
||||||
/**
|
/**
|
||||||
* Returns the value of a dice roll with n sides.
|
* Returns the value of a dice roll with n sides.
|
||||||
*
|
*
|
||||||
* @param sides - The number of sides on the dice
|
* @param sides - The number of sides on the dice
|
||||||
* @returns The value of a dice roll with n sides
|
* @returns The value of a dice roll with n sides
|
||||||
*/
|
*/
|
||||||
return Math.floor(Math.random() * sides) + 1
|
return Math.floor(Math.random() * sides) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
@ -616,7 +623,8 @@ export class UserAPI {
|
|||||||
*
|
*
|
||||||
* @returns The current iteration of global file
|
* @returns The current iteration of global file
|
||||||
*/
|
*/
|
||||||
return this.app.universes[this.app.selected_universe].global.evaluations as number;
|
return this.app.universes[this.app.selected_universe].global
|
||||||
|
.evaluations as number;
|
||||||
}
|
}
|
||||||
|
|
||||||
set i(n: number) {
|
set i(n: number) {
|
||||||
@ -633,7 +641,7 @@ export class UserAPI {
|
|||||||
*
|
*
|
||||||
* @returns The current bar number
|
* @returns The current bar number
|
||||||
*/
|
*/
|
||||||
return this.app.clock.time_position.bar
|
return this.app.clock.time_position.bar;
|
||||||
}
|
}
|
||||||
|
|
||||||
get tick(): number {
|
get tick(): number {
|
||||||
@ -642,7 +650,7 @@ export class UserAPI {
|
|||||||
*
|
*
|
||||||
* @returns The current tick number
|
* @returns The current tick number
|
||||||
*/
|
*/
|
||||||
return this.app.clock.tick
|
return this.app.clock.tick;
|
||||||
}
|
}
|
||||||
|
|
||||||
get pulse(): number {
|
get pulse(): number {
|
||||||
@ -651,7 +659,7 @@ export class UserAPI {
|
|||||||
*
|
*
|
||||||
* @returns The current pulse number
|
* @returns The current pulse number
|
||||||
*/
|
*/
|
||||||
return this.app.clock.time_position.pulse
|
return this.app.clock.time_position.pulse;
|
||||||
}
|
}
|
||||||
|
|
||||||
get beat(): number {
|
get beat(): number {
|
||||||
@ -660,7 +668,7 @@ export class UserAPI {
|
|||||||
*
|
*
|
||||||
* @returns The current beat number
|
* @returns The current beat number
|
||||||
*/
|
*/
|
||||||
return this.app.clock.time_position.beat
|
return this.app.clock.time_position.beat;
|
||||||
}
|
}
|
||||||
|
|
||||||
get ebeat(): number {
|
get ebeat(): number {
|
||||||
@ -668,15 +676,14 @@ export class UserAPI {
|
|||||||
* Returns the current beat number since the origin of time
|
* Returns the current beat number since the origin of time
|
||||||
* TODO: fix! Why is this not working?
|
* TODO: fix! Why is this not working?
|
||||||
*/
|
*/
|
||||||
return this.app.clock.beats_since_origin
|
return this.app.clock.beats_since_origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
onbar(n: number, ...bar: number[]): boolean {
|
onbar(n: number, ...bar: number[]): boolean {
|
||||||
// n is acting as a modulo on the bar number
|
// n is acting as a modulo on the bar number
|
||||||
const bar_list = [...Array(n).keys()].map(i => i + 1);
|
const bar_list = [...Array(n).keys()].map((i) => i + 1);
|
||||||
console.log(bar.some(b => bar_list.includes(b % n)))
|
console.log(bar.some((b) => bar_list.includes(b % n)));
|
||||||
return bar.some(b => bar_list.includes(b % n))
|
return bar.some((b) => bar_list.includes(b % n));
|
||||||
}
|
}
|
||||||
|
|
||||||
onbeat(...beat: number[]): boolean {
|
onbeat(...beat: number[]): boolean {
|
||||||
@ -689,17 +696,18 @@ export class UserAPI {
|
|||||||
* @param beat - The beats to check
|
* @param beat - The beats to check
|
||||||
* @returns True if the current beat is in the given list of beats
|
* @returns True if the current beat is in the given list of beats
|
||||||
*/
|
*/
|
||||||
let final_pulses: boolean[] = []
|
let final_pulses: boolean[] = [];
|
||||||
beat.forEach(b => {
|
beat.forEach((b) => {
|
||||||
b = 1 + (b % this.app.clock.time_signature[0])
|
b = 1 + (b % this.app.clock.time_signature[0]);
|
||||||
let integral_part = Math.floor(b);
|
let integral_part = Math.floor(b);
|
||||||
let decimal_part = b - integral_part;
|
let decimal_part = b - integral_part;
|
||||||
final_pulses.push(
|
final_pulses.push(
|
||||||
integral_part === this.app.clock.time_position.beat &&
|
integral_part === this.app.clock.time_position.beat &&
|
||||||
this.app.clock.time_position.pulse === decimal_part * this.app.clock.ppqn
|
this.app.clock.time_position.pulse ===
|
||||||
)
|
decimal_part * this.app.clock.ppqn
|
||||||
|
);
|
||||||
});
|
});
|
||||||
return final_pulses.some(p => p == true)
|
return final_pulses.some((p) => p == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
stop(): void {
|
stop(): void {
|
||||||
@ -709,11 +717,11 @@ export class UserAPI {
|
|||||||
* @see silence
|
* @see silence
|
||||||
* @see hush
|
* @see hush
|
||||||
*/
|
*/
|
||||||
this.app.clock.pause()
|
this.app.clock.pause();
|
||||||
this.app.setButtonHighlighting("pause", true);
|
this.app.setButtonHighlighting("pause", true);
|
||||||
}
|
}
|
||||||
silence = this.stop
|
silence = this.stop;
|
||||||
hush = this.stop
|
hush = this.stop;
|
||||||
|
|
||||||
prob(p: number): boolean {
|
prob(p: number): boolean {
|
||||||
/**
|
/**
|
||||||
@ -722,7 +730,7 @@ export class UserAPI {
|
|||||||
* @param p - The probability of returning true
|
* @param p - The probability of returning true
|
||||||
* @returns True p% of the time
|
* @returns True p% of the time
|
||||||
*/
|
*/
|
||||||
return Math.random() * 100 < p
|
return Math.random() * 100 < p;
|
||||||
}
|
}
|
||||||
|
|
||||||
toss(): boolean {
|
toss(): boolean {
|
||||||
@ -736,7 +744,7 @@ export class UserAPI {
|
|||||||
* @see almostAlways
|
* @see almostAlways
|
||||||
* @see almostNever
|
* @see almostNever
|
||||||
*/
|
*/
|
||||||
return Math.random() > 0.5
|
return Math.random() > 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
min(...values: number[]): number {
|
min(...values: number[]): number {
|
||||||
@ -746,7 +754,7 @@ export class UserAPI {
|
|||||||
* @param values - The list of numbers
|
* @param values - The list of numbers
|
||||||
* @returns The minimum value of the list of numbers
|
* @returns The minimum value of the list of numbers
|
||||||
*/
|
*/
|
||||||
return Math.min(...values)
|
return Math.min(...values);
|
||||||
}
|
}
|
||||||
|
|
||||||
max(...values: number[]): number {
|
max(...values: number[]): number {
|
||||||
@ -756,7 +764,7 @@ export class UserAPI {
|
|||||||
* @param values - The list of numbers
|
* @param values - The list of numbers
|
||||||
* @returns The maximum value of the list of numbers
|
* @returns The maximum value of the list of numbers
|
||||||
*/
|
*/
|
||||||
return Math.max(...values)
|
return Math.max(...values);
|
||||||
}
|
}
|
||||||
|
|
||||||
limit(value: number, min: number, max: number): number {
|
limit(value: number, min: number, max: number): number {
|
||||||
@ -768,10 +776,9 @@ export class UserAPI {
|
|||||||
* @param max - The maximum value
|
* @param max - The maximum value
|
||||||
* @returns The limited value
|
* @returns The limited value
|
||||||
*/
|
*/
|
||||||
return Math.min(Math.max(value, min), max)
|
return Math.min(Math.max(value, min), max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
delay(ms: number, func: Function): void {
|
delay(ms: number, func: Function): void {
|
||||||
/**
|
/**
|
||||||
* Delays the execution of a function by a given number of milliseconds.
|
* Delays the execution of a function by a given number of milliseconds.
|
||||||
@ -780,7 +787,7 @@ export class UserAPI {
|
|||||||
* @param func - The function to execute
|
* @param func - The function to execute
|
||||||
* @returns The current time signature
|
* @returns The current time signature
|
||||||
*/
|
*/
|
||||||
setTimeout(func, ms)
|
setTimeout(func, ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
delayr(ms: number, nb: number, func: Function): void {
|
delayr(ms: number, nb: number, func: Function): void {
|
||||||
@ -792,9 +799,9 @@ export class UserAPI {
|
|||||||
* @param func - The function to execute
|
* @param func - The function to execute
|
||||||
* @returns The current time signature
|
* @returns The current time signature
|
||||||
*/
|
*/
|
||||||
const list = [...Array(nb).keys()].map(i => ms * i);
|
const list = [...Array(nb).keys()].map((i) => ms * i);
|
||||||
list.forEach((ms, _) => {
|
list.forEach((ms, _) => {
|
||||||
setTimeout(func, ms)
|
setTimeout(func, ms);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -805,7 +812,7 @@ export class UserAPI {
|
|||||||
* @param pulse - The pulse to check for
|
* @param pulse - The pulse to check for
|
||||||
* @returns True if the current pulse is a modulo of any of the given pulses
|
* @returns True if the current pulse is a modulo of any of the given pulses
|
||||||
*/
|
*/
|
||||||
return pulse.some(p => this.app.clock.time_position.pulse % p === 0)
|
return pulse.some((p) => this.app.clock.time_position.pulse % p === 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
modbar(...bar: number[]): boolean {
|
modbar(...bar: number[]): boolean {
|
||||||
@ -816,10 +823,15 @@ export class UserAPI {
|
|||||||
* @returns True if the current bar is a modulo of any of the given bars
|
* @returns True if the current bar is a modulo of any of the given bars
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
return bar.some(b => this.app.clock.time_position.bar % b === 0)
|
return bar.some((b) => this.app.clock.time_position.bar % b === 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
euclid(iterator: number, pulses: number, length: number, rotate: number=0): boolean {
|
euclid(
|
||||||
|
iterator: number,
|
||||||
|
pulses: number,
|
||||||
|
length: number,
|
||||||
|
rotate: number = 0
|
||||||
|
): boolean {
|
||||||
/**
|
/**
|
||||||
* Returns a euclidean cycle of size length, with n pulses, rotated or not.
|
* Returns a euclidean cycle of size length, with n pulses, rotated or not.
|
||||||
*
|
*
|
||||||
@ -832,16 +844,23 @@ export class UserAPI {
|
|||||||
return this._euclidean_cycle(pulses, length, rotate)[iterator % length];
|
return this._euclidean_cycle(pulses, length, rotate)[iterator % length];
|
||||||
}
|
}
|
||||||
|
|
||||||
_euclidean_cycle(pulses: number, length: number, rotate: number = 0): boolean[] {
|
_euclidean_cycle(
|
||||||
|
pulses: number,
|
||||||
|
length: number,
|
||||||
|
rotate: number = 0
|
||||||
|
): boolean[] {
|
||||||
function startsDescent(list: number[], i: number): boolean {
|
function startsDescent(list: number[], i: number): boolean {
|
||||||
const length = list.length;
|
const length = list.length;
|
||||||
const nextIndex = (i + 1) % length;
|
const nextIndex = (i + 1) % length;
|
||||||
return list[i] > list[nextIndex] ? true : false;
|
return list[i] > list[nextIndex] ? true : false;
|
||||||
}
|
}
|
||||||
if (pulses >= length) return [true];
|
if (pulses >= length) return [true];
|
||||||
const resList = Array.from({length}, (_, i) => ((pulses * (i - 1)) % length + length) % length);
|
const resList = Array.from(
|
||||||
|
{ length },
|
||||||
|
(_, i) => (((pulses * (i - 1)) % length) + length) % length
|
||||||
|
);
|
||||||
let cycle = resList.map((_, i) => startsDescent(resList, i));
|
let cycle = resList.map((_, i) => startsDescent(resList, i));
|
||||||
if(rotate!=0) {
|
if (rotate != 0) {
|
||||||
cycle = cycle.slice(rotate).concat(cycle.slice(0, rotate));
|
cycle = cycle.slice(rotate).concat(cycle.slice(0, rotate));
|
||||||
}
|
}
|
||||||
return cycle;
|
return cycle;
|
||||||
@ -860,6 +879,14 @@ export class UserAPI {
|
|||||||
return tobin[iterator % tobin.length];
|
return tobin[iterator % tobin.length];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gold() {
|
||||||
|
/**
|
||||||
|
* Essayer de générer des séquences tirées du truc de Puckette
|
||||||
|
* Faire ça avec des lazy lists, ça ne devrait pas être trop difficle.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
// Low Frequency Oscillators
|
// Low Frequency Oscillators
|
||||||
// =============================================================
|
// =============================================================
|
||||||
@ -886,7 +913,7 @@ export class UserAPI {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
sine(freq: number = 1, offset: number=0): number {
|
sine(freq: number = 1, offset: number = 0): number {
|
||||||
/**
|
/**
|
||||||
* Returns a sine wave between -1 and 1.
|
* Returns a sine wave between -1 and 1.
|
||||||
*
|
*
|
||||||
@ -894,10 +921,12 @@ export class UserAPI {
|
|||||||
* @param offset - The offset of the sine wave
|
* @param offset - The offset of the sine wave
|
||||||
* @returns A sine wave between -1 and 1
|
* @returns A sine wave between -1 and 1
|
||||||
*/
|
*/
|
||||||
return Math.sin(this.app.clock.ctx.currentTime * Math.PI * 2 * freq) + offset
|
return (
|
||||||
|
Math.sin(this.app.clock.ctx.currentTime * Math.PI * 2 * freq) + offset
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
saw(freq: number = 1, offset: number=0): number {
|
saw(freq: number = 1, offset: number = 0): number {
|
||||||
/**
|
/**
|
||||||
* Returns a saw wave between -1 and 1.
|
* Returns a saw wave between -1 and 1.
|
||||||
*
|
*
|
||||||
@ -909,10 +938,10 @@ export class UserAPI {
|
|||||||
* @see sine
|
* @see sine
|
||||||
* @see noise
|
* @see noise
|
||||||
*/
|
*/
|
||||||
return (this.app.clock.ctx.currentTime * freq) % 1 * 2 - 1 + offset
|
return ((this.app.clock.ctx.currentTime * freq) % 1) * 2 - 1 + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
triangle(freq: number = 1, offset: number=0): number {
|
triangle(freq: number = 1, offset: number = 0): number {
|
||||||
/**
|
/**
|
||||||
* Returns a triangle wave between -1 and 1.
|
* Returns a triangle wave between -1 and 1.
|
||||||
*
|
*
|
||||||
@ -922,10 +951,10 @@ export class UserAPI {
|
|||||||
* @see sine
|
* @see sine
|
||||||
* @see noise
|
* @see noise
|
||||||
*/
|
*/
|
||||||
return Math.abs(this.saw(freq, offset)) * 2 - 1
|
return Math.abs(this.saw(freq, offset)) * 2 - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
square(freq: number = 1, offset: number=0): number {
|
square(freq: number = 1, offset: number = 0): number {
|
||||||
/**
|
/**
|
||||||
* Returns a square wave between -1 and 1.
|
* Returns a square wave between -1 and 1.
|
||||||
*
|
*
|
||||||
@ -935,7 +964,7 @@ export class UserAPI {
|
|||||||
* @see sine
|
* @see sine
|
||||||
* @see noise
|
* @see noise
|
||||||
*/
|
*/
|
||||||
return this.saw(freq, offset) > 0 ? 1 : -1
|
return this.saw(freq, offset) > 0 ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
noise(): number {
|
noise(): number {
|
||||||
@ -949,21 +978,23 @@ export class UserAPI {
|
|||||||
* @see sine
|
* @see sine
|
||||||
* @see noise
|
* @see noise
|
||||||
*/
|
*/
|
||||||
return Math.random() * 2 - 1
|
return Math.random() * 2 - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
// Math functions
|
// Math functions
|
||||||
// =============================================================
|
// =============================================================
|
||||||
|
|
||||||
abs = Math.abs
|
abs = Math.abs;
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
// Trivial functions
|
// Trivial functions
|
||||||
// =============================================================
|
// =============================================================
|
||||||
|
|
||||||
sound = async (values: object, delay: number = 0.00) => {
|
sound = async (values: object, delay: number = 0.0) => {
|
||||||
superdough(values, delay)
|
superdough(values, delay);
|
||||||
}
|
};
|
||||||
d = this.sound
|
d = this.sound;
|
||||||
|
|
||||||
|
samples = samples;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +1,15 @@
|
|||||||
import type { Editor } from './main';
|
import type { Editor } from "./main";
|
||||||
import type { File } from './AppSettings';
|
import type { File } from "./AppSettings";
|
||||||
|
|
||||||
function codeInterceptor(code: string): string {
|
const delay = (ms: number) =>
|
||||||
return code
|
new Promise((_, reject) =>
|
||||||
.replace(/->/g, "&&")
|
setTimeout(() => reject(new Error("Operation took too long")), ms)
|
||||||
.replace(/t\[(\d+),(\d+)\]/g, 'mod($1,$2)')
|
);
|
||||||
.replace(/b\[(\d+),(\d+)\]/g, '[$1,$2].includes(beat)')
|
|
||||||
.replace(/eb\[(\d+),(\d+)\]/g, '[$1,$2].includes(ebeat)')
|
|
||||||
.replace(/m\[(\d+),(\d+)\]/g, '[$1,$2].includes(bar)');
|
|
||||||
}
|
|
||||||
|
|
||||||
const delay = (ms: number) => new Promise((_, reject) => setTimeout(() => reject(new Error('Operation took too long')), ms));
|
const tryCatchWrapper = (
|
||||||
|
application: Editor,
|
||||||
const tryCatchWrapper = (application: Editor, code: string): Promise<boolean> => {
|
code: string
|
||||||
|
): Promise<boolean> => {
|
||||||
/**
|
/**
|
||||||
* This function wraps a string of code in a try/catch block and returns a promise
|
* This function wraps a string of code in a try/catch block and returns a promise
|
||||||
* that resolves to true if the code is valid and false if the code is invalid after
|
* that resolves to true if the code is valid and false if the code is invalid after
|
||||||
@ -24,14 +21,16 @@ const tryCatchWrapper = (application: Editor, code: string): Promise<boolean> =>
|
|||||||
*/
|
*/
|
||||||
return new Promise((resolve, _) => {
|
return new Promise((resolve, _) => {
|
||||||
try {
|
try {
|
||||||
Function(`with (this) {try{${codeInterceptor(code)}} catch (e) {console.log(e)}};`).call(application.api);
|
Function(`with (this) {try{${code}} catch (e) {console.log(e)}};`).call(
|
||||||
|
application.api
|
||||||
|
);
|
||||||
resolve(true);
|
resolve(true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
resolve(false);
|
resolve(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export const tryEvaluate = async (
|
export const tryEvaluate = async (
|
||||||
/**
|
/**
|
||||||
@ -47,13 +46,16 @@ export const tryEvaluate = async (
|
|||||||
application: Editor,
|
application: Editor,
|
||||||
code: File,
|
code: File,
|
||||||
timeout = 5000
|
timeout = 5000
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
code.evaluations!++;
|
code.evaluations!++;
|
||||||
const isCodeValid = await Promise.race([tryCatchWrapper(
|
const isCodeValid = await Promise.race([
|
||||||
|
tryCatchWrapper(
|
||||||
application,
|
application,
|
||||||
`let i = ${code.evaluations};` + codeInterceptor(code.candidate as string),
|
(`let i = ${code.evaluations};` + code.candidate) as string
|
||||||
), delay(timeout)]);
|
),
|
||||||
|
delay(timeout),
|
||||||
|
]);
|
||||||
|
|
||||||
if (isCodeValid) {
|
if (isCodeValid) {
|
||||||
code.committed = code.candidate;
|
code.committed = code.candidate;
|
||||||
@ -63,9 +65,13 @@ export const tryEvaluate = async (
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
export const evaluate = async (application: Editor, code: File, timeout = 1000): Promise<void> => {
|
export const evaluate = async (
|
||||||
|
application: Editor,
|
||||||
|
code: File,
|
||||||
|
timeout = 1000
|
||||||
|
): Promise<void> => {
|
||||||
/**
|
/**
|
||||||
* This function evaluates a string of code in the context of user API.
|
* This function evaluates a string of code in the context of user API.
|
||||||
*
|
*
|
||||||
@ -75,10 +81,12 @@ export const evaluate = async (application: Editor, code: File, timeout = 1000):
|
|||||||
* @returns A promise that resolves to void
|
* @returns A promise that resolves to void
|
||||||
*/
|
*/
|
||||||
try {
|
try {
|
||||||
await Promise.race([tryCatchWrapper(application, codeInterceptor(code.committed as string)), delay(timeout)]);
|
await Promise.race([
|
||||||
if (code.evaluations)
|
tryCatchWrapper(application, code.committed as string),
|
||||||
code.evaluations++;
|
delay(timeout),
|
||||||
|
]);
|
||||||
|
if (code.evaluations) code.evaluations++;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|||||||
@ -1160,7 +1160,11 @@ yaml@^2.1.1:
|
|||||||
|
|
||||||
"zifferjs@https://github.com/amiika/zifferjs.git":
|
"zifferjs@https://github.com/amiika/zifferjs.git":
|
||||||
version "0.0.0"
|
version "0.0.0"
|
||||||
|
<<<<<<< HEAD
|
||||||
resolved "https://github.com/amiika/zifferjs.git#374ee4edb0b07d9968b635f899f9f88d79ddaa07"
|
resolved "https://github.com/amiika/zifferjs.git#374ee4edb0b07d9968b635f899f9f88d79ddaa07"
|
||||||
|
=======
|
||||||
|
resolved "https://github.com/amiika/zifferjs.git#0254770c19db8772a9c3cb6b0571f2b5007593e6"
|
||||||
|
>>>>>>> 3effb4f456592922e3e97e1e7b16f6f8929a90b4
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/seedrandom" "^3.0.5"
|
"@types/seedrandom" "^3.0.5"
|
||||||
lru-cache "^10.0.0"
|
lru-cache "^10.0.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user