♻️ switching to typescript

This commit is contained in:
2019-12-10 15:10:55 +01:00
parent d9aebffa57
commit 0ddbec99ed
25 changed files with 103 additions and 53 deletions

24
package-lock.json generated
View File

@@ -1243,6 +1243,11 @@
"@babel/types": "^7.3.0" "@babel/types": "^7.3.0"
} }
}, },
"@types/css-font-loading-module": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.2.tgz",
"integrity": "sha512-zZTq/B1ZcJMepOfBIMEwOZ/g/jpSPUJoxP8zPtPizOKE/Q89SujK1BLYZBg+4LLW3IzJGOI67dbeePy8uPUs+g=="
},
"@types/istanbul-lib-coverage": { "@types/istanbul-lib-coverage": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz",
@@ -1277,12 +1282,25 @@
"jest-diff": "^24.3.0" "jest-diff": "^24.3.0"
} }
}, },
"@types/node": {
"version": "12.12.16",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.16.tgz",
"integrity": "sha512-vRuMyoOr5yfNf8QWxXegOjeyjpWJxFePzHzmBOIzDIzo+rSqF94RW0PkS6y4T2+VjAWLXHWrfbIJY3E3aS7lUw=="
},
"@types/stack-utils": { "@types/stack-utils": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
"integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==",
"dev": true "dev": true
}, },
"@types/uuid": {
"version": "3.4.6",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.6.tgz",
"integrity": "sha512-cCdlC/1kGEZdEglzOieLDYBxHsvEOIg7kp/2FYyVR9Pxakq+Qf/inL3RKQ+PA8gOlI/NnL+fXmQH12nwcGzsHw==",
"requires": {
"@types/node": "*"
}
},
"@types/yargs": { "@types/yargs": {
"version": "13.0.3", "version": "13.0.3",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.3.tgz", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.3.tgz",
@@ -5553,6 +5571,12 @@
"prelude-ls": "~1.1.2" "prelude-ls": "~1.1.2"
} }
}, },
"typescript": {
"version": "3.7.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.3.tgz",
"integrity": "sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw==",
"dev": true
},
"uglify-js": { "uglify-js": {
"version": "3.7.1", "version": "3.7.1",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.1.tgz", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.1.tgz",

View File

@@ -6,6 +6,7 @@
"scripts": { "scripts": {
"dev": "webpack-dev-server --quiet --progress --watch --mode development", "dev": "webpack-dev-server --quiet --progress --watch --mode development",
"build": "webpack --mode production --quiet --progress", "build": "webpack --mode production --quiet --progress",
"ts-check": "tsc --noEmit --project tsconfig.json",
"test": "jest" "test": "jest"
}, },
"keywords": [ "keywords": [
@@ -22,9 +23,12 @@
"@types/jest": "^24.0.0", "@types/jest": "^24.0.0",
"babel-jest": "^24.6.0", "babel-jest": "^24.6.0",
"babel-polyfill": "^6.26.0", "babel-polyfill": "^6.26.0",
"jest": "^24.9.0" "jest": "^24.9.0",
"typescript": "^3.7.3"
}, },
"dependencies": { "dependencies": {
"@types/css-font-loading-module": "0.0.2",
"@types/uuid": "^3.4.6",
"uuid": "^3.3.3" "uuid": "^3.3.3"
}, },
"jest": { "jest": {

View File

@@ -1,4 +1,4 @@
type PoolCanvas<T extends (OffscreenCanvas | HTMLCanvasElement)> = T & { export type PoolCanvas<T extends (OffscreenCanvas | HTMLCanvasElement)> = T & {
acquire(): void acquire(): void
release(): void release(): void
} }

View File

@@ -1,16 +1,20 @@
export class Subject { type Listener<V> = ((val: V) => void);
export class Subject<V> {
__listeners: Listener<V>[]
constructor() { constructor() {
this.__listeners = []; this.__listeners = [];
} }
next(val) { next(val:V) {
for (let listener of this.__listeners) { for (let listener of this.__listeners) {
listener(val); listener(val);
} }
} }
once() { once():Promise<V> {
return new Promise((resolve) => { return new Promise((resolve) => {
const done = (val) => { const done = (val) => {
resolve(val); resolve(val);
@@ -20,11 +24,11 @@ export class Subject {
}) })
} }
on(fn) { on(fn:Listener<V>) {
this.__listeners.push(fn); this.__listeners.push(fn);
} }
off(fn) { off(fn:Listener<V>) {
this.__listeners = this.__listeners.filter((listener) => listener !== fn); this.__listeners = this.__listeners.filter((listener) => listener !== fn);
} }
@@ -33,11 +37,12 @@ export class Subject {
} }
} }
export class MultiSubject { export class MultiSubject {
__subjects: {
[name: string]: Subject<any>
}
constructor(types) { constructor(types: string[]) {
this.__subjects = {}; this.__subjects = {};
for (let type of types) { for (let type of types) {
this.__subjects[type] = new Subject(); this.__subjects[type] = new Subject();

View File

@@ -5,13 +5,17 @@ import {
Variables, Variables,
ImageVar, ImageVar,
BooleanVar, BooleanVar,
NumberVar NumberVar,
VariableValueType
} from '../io/AbstractIOSet'; } from '../io/AbstractIOSet';
const inputs = { const inputs = {
image: { image: {
type: 'Image', type: 'Image',
} as ImageVar, } as ImageVar,
width: {
type: 'Number',
} as NumberVar,
}; };
const outputs = { const outputs = {
@@ -29,11 +33,10 @@ const outputs = {
export default class Canvas2d<I extends Variables, O extends Variables> extends Node<I & (typeof inputs), O & (typeof outputs)> { export default class Canvas2d<I extends Variables, O extends Variables> extends Node<I & (typeof inputs), O & (typeof outputs)> {
constructor(name, inputDefinition: I, outputDefiniton: O, options) { constructor(name, inputDefinition: I, outputDefiniton: O) {
super(name, super(name,
merge(inputs, inputDefinition), merge(inputs, inputDefinition),
merge(outputs, outputDefiniton), merge(outputs, outputDefiniton),
options
); );
} }
@@ -42,7 +45,11 @@ export default class Canvas2d<I extends Variables, O extends Variables> extends
} }
async _update() { async _update() {
const values = {}; type valuesType = {
[K in keyof I]: VariableValueType<I[K]['type']>;
}
const values:valuesType = <valuesType>{};
for (let name of Object.keys(this.in.variables)) { for (let name of Object.keys(this.in.variables)) {
values[name] = await waitForMedia(this.in[name].value); values[name] = await waitForMedia(this.in[name].value);
} }

View File

@@ -1,4 +1,5 @@
import Canvas2d from './Canvas2d'; import Canvas2d from './Canvas2d';
import {PoolCanvas} from '../../canvas/CanvasPool';
import {createCanvas, mediaSize, paintToCanvas} from '../canvas'; import {createCanvas, mediaSize, paintToCanvas} from '../canvas';
import { import {
ImageVar, ImageVar,
@@ -89,7 +90,7 @@ const outputs = {
export default class Compose extends Canvas2d<typeof inputs, typeof outputs> { export default class Compose extends Canvas2d<typeof inputs, typeof outputs> {
constructor(options={}) { constructor(options={}) {
super('Compose', inputs, outputs, options); super('Compose', inputs, outputs);
} }
get width() { get width() {
@@ -149,13 +150,13 @@ export default class Compose extends Canvas2d<typeof inputs, typeof outputs> {
ctx.globalCompositeOperation = 'source-over'; ctx.globalCompositeOperation = 'source-over';
if (this.bg) { if (this.bg) {
paintToCanvas(canvas, this.bg.image, this.bg); paintToCanvas(canvas, <PoolCanvas<any>>this.bg.image, this.bg);
} }
ctx.globalCompositeOperation = mode; ctx.globalCompositeOperation = mode;
if (this.fg) { if (this.fg) {
paintToCanvas(canvas, this.fg.image, this.fg); paintToCanvas(canvas, <PoolCanvas<any>>this.fg.image, this.fg);
} }
return canvas; return canvas;

View File

@@ -29,7 +29,7 @@ const outputs = {
export default class EmptySpace extends Canvas2d<typeof inputs, typeof outputs> { export default class EmptySpace extends Canvas2d<typeof inputs, typeof outputs> {
constructor() { constructor() {
super('EmptySpace', inputs, outputs, {}); super('EmptySpace', inputs, outputs);
this._update(); this._update();
} }

View File

@@ -20,7 +20,7 @@ const outputs = {};
export default class Flip extends Canvas2d<typeof inputs, typeof outputs> { export default class Flip extends Canvas2d<typeof inputs, typeof outputs> {
constructor() { constructor() {
super('Flip', inputs, outputs, {}); super('Flip', inputs, outputs);
this._update(); this._update();
} }

View File

@@ -1,3 +1,4 @@
// @ts-nocheck
import Node from './Canvas2d'; import Node from './Canvas2d';
import {waitForMedia} from '../../utils'; import {waitForMedia} from '../../utils';
import {createCanvas, mediaSize, paintToCanvas} from '../canvas'; import {createCanvas, mediaSize, paintToCanvas} from '../canvas';

View File

@@ -1,6 +1,6 @@
import Canvas2d from './Canvas2d'; import Canvas2d from './Canvas2d';
import {waitForMedia} from '../../utils'; import {waitForMedia} from '../../utils';
import {createCanvas, mediaSize, paintToCanvas} from '../canvas'; import {createCanvas, mediaSize, paintToCanvas, Bounds} from '../canvas';
import { import {
ImageVar, ImageVar,
StringVar, StringVar,
@@ -27,7 +27,7 @@ const outputs = {};
export default class Resize extends Canvas2d<typeof inputs, typeof outputs> { export default class Resize extends Canvas2d<typeof inputs, typeof outputs> {
constructor() { constructor() {
super('Resize', inputs, outputs, {}); super('Resize', inputs, outputs);
} }
/** /**
@@ -52,7 +52,7 @@ export default class Resize extends Canvas2d<typeof inputs, typeof outputs> {
const {width: destWidth, height: destHeight} = mediaSize(canvas); const {width: destWidth, height: destHeight} = mediaSize(canvas);
const srcAspectRatio = (srcWidth / srcHeight); const srcAspectRatio = (srcWidth / srcHeight);
const destAspectRatio = (destWidth / destHeight); const destAspectRatio = (destWidth / destHeight);
const newImage = {}; const newImage:Partial<Bounds> = {};
if (srcAspectRatio > destAspectRatio) { if (srcAspectRatio > destAspectRatio) {
newImage.width = destHeight * srcAspectRatio; newImage.width = destHeight * srcAspectRatio;
newImage.height = destHeight; newImage.height = destHeight;
@@ -64,7 +64,7 @@ export default class Resize extends Canvas2d<typeof inputs, typeof outputs> {
newImage.top = (destHeight - newImage.height) / 2; newImage.top = (destHeight - newImage.height) / 2;
newImage.left = (destWidth - newImage.width) / 2; newImage.left = (destWidth - newImage.width) / 2;
paintToCanvas(canvas, media, newImage); paintToCanvas(canvas, media, <Bounds>newImage);
return canvas; return canvas;
} }
} }

View File

@@ -65,7 +65,7 @@ const outputs = {};
export default class Resize extends Canvas2d<typeof inputs, typeof outputs> { export default class Resize extends Canvas2d<typeof inputs, typeof outputs> {
constructor() { constructor() {
super('Text', inputs, outputs, {}); super('Text', inputs, outputs);
this._update(); this._update();
} }

View File

@@ -26,7 +26,7 @@ const outputs = {
export default class Disable extends Node<typeof inputs, typeof outputs> { export default class Disable extends Node<typeof inputs, typeof outputs> {
constructor() { constructor() {
super('Disable', inputs, outputs, {}); super('Disable', inputs, outputs);
} }
async _update() { async _update() {

View File

@@ -36,7 +36,7 @@ const outputs = {
export default class Font extends Node<typeof inputs, typeof outputs> { export default class Font extends Node<typeof inputs, typeof outputs> {
constructor() { constructor() {
super('Font', inputs, outputs, {}); super('Font', inputs, outputs);
} }
async _update() { async _update() {

View File

@@ -36,7 +36,7 @@ const outputs = {
export default class NumberBinaryOperation extends Node<typeof inputs, typeof outputs> { export default class NumberBinaryOperation extends Node<typeof inputs, typeof outputs> {
constructor() { constructor() {
super('NumberBinaryOperation', inputs, outputs, {}); super('NumberBinaryOperation', inputs, outputs);
} }
async _update() { async _update() {

View File

@@ -37,7 +37,7 @@ const outputs = {
export default class Numbers extends Node<typeof inputs, typeof outputs> { export default class Numbers extends Node<typeof inputs, typeof outputs> {
constructor() { constructor() {
super('Numbers', inputs, outputs, {}); super('Numbers', inputs, outputs);
} }
async _update() { async _update() {

View File

@@ -1,5 +1,5 @@
import {Inputs, Outputs} from './io/index'; import {Inputs, Outputs} from './io/index';
import uuidv4 from 'uuid/v4'; import { v4 as uuid } from 'uuid';
import {Variables, InputProperties, OutputProperties} from './io/AbstractIOSet'; import {Variables, InputProperties, OutputProperties} from './io/AbstractIOSet';
import {MultiSubject} from '../helpers/listener'; import {MultiSubject} from '../helpers/listener';
@@ -16,10 +16,10 @@ export default class Node<I extends Variables, O extends Variables> {
_stopped: boolean _stopped: boolean
subject: MultiSubject subject: MultiSubject
constructor(name: string, inputDefinition: I, outputDefiniton: O, options) { constructor(name: string, inputDefinition: I, outputDefiniton: O) {
this.name = name; this.name = name;
this.uid = uuidv4(); this.uid = uuid();
this.id = uuidv4(); this.id = uuid();
this.__in = new Inputs(inputDefinition, this) as Inputs<I> & InputProperties<I>; this.__in = new Inputs(inputDefinition, this) as Inputs<I> & InputProperties<I>;
this.__out = new Outputs(outputDefiniton, this) as Outputs<O> & OutputProperties<O>; this.__out = new Outputs(outputDefiniton, this) as Outputs<O> & OutputProperties<O>;
this.__in.update = (name) => this.__update([name]); this.__in.update = (name) => this.__update([name]);
@@ -95,7 +95,7 @@ export default class Node<I extends Variables, O extends Variables> {
} }
async deserialize({id, options}) { async deserialize({id, options}) {
this.id = id || uuidv4(); this.id = id || uuid();
} }
async reconnect({options}, outputs) { async reconnect({options}, outputs) {

View File

@@ -1,3 +1,4 @@
// @ts-nocheck
import Node from './Node'; import Node from './Node';
export default class Numbers extends Node { export default class Numbers extends Node {

View File

@@ -1,3 +1,4 @@
// @ts-nocheck
import Node from './Node'; import Node from './Node';
import {createCanvas} from './canvas'; import {createCanvas} from './canvas';

View File

@@ -1,19 +1,19 @@
import WebGL from './WebGl'; import WebGL from './WebGl';
import {
NumberVar
} from '../io/AbstractIOSet';
const inputs = {
export default class Sepia extends WebGL {
constructor() {
super('Tint', {
amount: { amount: {
type: 'Number', type: 'Number',
default: 0, default: 0,
}, } as NumberVar,
amount: { }
type: 'Color',
default: '', export default class Sepia extends WebGL<typeof inputs> {
},
}) constructor() {
super('Tint', inputs)
} }
get frag() { get frag() {

View File

@@ -1,7 +1,7 @@
import Node from '../Node'; import Node from '../Node';
import {createCanvas, mediaSize, paintToCanvas} from '../canvas'; import {createCanvas, mediaSize, paintToCanvas} from '../canvas';
import {merge} from '../../utils'; import {merge} from '../../utils';
import {canvasPool2D} from '../../canvas/CanvasPool'; import {canvasPool2D, PoolCanvas} from '../../canvas/CanvasPool';
import { import {
Variables, Variables,
ImageVar, ImageVar,
@@ -36,7 +36,6 @@ export default class WebGL<I extends Variables> extends Node<I & (typeof inputs)
name, name,
merge(inputs, inputDefinition), merge(inputs, inputDefinition),
outputs, outputs,
{}
) )
} }
@@ -166,7 +165,11 @@ export default class WebGL<I extends Variables> extends Node<I & (typeof inputs)
_passes() { _passes() {
return [ return [
(gl: WebGLRenderingContext, program: WebGLProgram, image) => { (
gl: WebGLRenderingContext,
program: WebGLProgram,
// image
) => {
this._setParams(gl, program); this._setParams(gl, program);
}, },
] ]
@@ -190,7 +193,7 @@ export default class WebGL<I extends Variables> extends Node<I & (typeof inputs)
async _update() { async _update() {
const image = this.in.image.value; const image = <PoolCanvas<any>>this.in.image.value;
if (!image) { if (!image) {
return; return;
} }
@@ -230,7 +233,7 @@ export default class WebGL<I extends Variables> extends Node<I & (typeof inputs)
if (this.image) { if (this.image) {
// Upload the image into the texture. // Upload the image into the texture.
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, await createImageBitmap(this.image)); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, await createImageBitmap(<PoolCanvas<any>>this.image));
} }
const texcoordBuffer = gl.createBuffer(); const texcoordBuffer = gl.createBuffer();
@@ -309,8 +312,8 @@ export default class WebGL<I extends Variables> extends Node<I & (typeof inputs)
if (image.release) { if (image.release) {
image.release(); image.release();
} }
if (this.out.image.value && this.out.image.value.release) { if (this.out.image.value && (<PoolCanvas<any>>this.out.image.value).release) {
this.out.image.value.release(); (<PoolCanvas<any>>this.out.image.value).release();
} }
this.out.image.value = resultCanvas; this.out.image.value = resultCanvas;
if (this.out.width.value !== this.out.image.value.width) { if (this.out.width.value !== this.out.image.value.width) {

View File

@@ -32,6 +32,7 @@ export default class Webcam extends Node {
/** @type {HTMLVideoElement} */ /** @type {HTMLVideoElement} */
const video = document.createElement('video'); const video = document.createElement('video');
// @ts-ignore
video.playsinline = true; video.playsinline = true;
video.srcObject = stream; video.srcObject = stream;
video.play(); video.play();

View File

@@ -8,7 +8,7 @@ import {serialize, deserialize} from './serializer';
export default class Input<V extends Variable> extends AbstractIO<V> { export default class Input<V extends Variable> extends AbstractIO<V> {
__output: Output<any> __output: Output<V>
__onchangelistener: Function __onchangelistener: Function
constructor(name, definition, owner) { constructor(name, definition, owner) {
@@ -35,7 +35,7 @@ export default class Input<V extends Variable> extends AbstractIO<V> {
return this.__output; return this.__output;
} }
connect(output: Output<any>) { connect(output: Output<V>) {
if (output && output.type === this.type) { if (output && output.type === this.type) {
this.disconnect(); this.disconnect();
this.__output = output this.__output = output

View File

@@ -24,6 +24,7 @@ describe('Inputs', () => {
type: 'String', type: 'String',
default: 'foo' default: 'foo'
}, },
// @ts-ignore
}, owner) }, owner)
expect(inputs.x.type).toBe('Number'); expect(inputs.x.type).toBe('Number');

View File

@@ -21,6 +21,7 @@ describe('Outputs', () => {
type: 'String', type: 'String',
default: 'foo' default: 'foo'
}, },
// @ts-ignore
}, owner) }, owner)
expect(inputs.x.type).toBe('Number'); expect(inputs.x.type).toBe('Number');