Skip to content

Commit

Permalink
Generate TypeScript definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
Zalastax committed Jan 1, 2018
1 parent 5501304 commit 09eed16
Show file tree
Hide file tree
Showing 5 changed files with 387 additions and 2 deletions.
7 changes: 6 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,11 @@ module.exports = function(grunt) {
// Load release task
grunt.loadTasks('tasks/release');

// Load typescript task
grunt.registerTask('typescript', function () {
require('./tasks/typescript/task.js')(grunt);
});

// Load the external libraries used.
grunt.loadNpmTasks('grunt-contrib-compress');
grunt.loadNpmTasks('grunt-contrib-connect');
Expand Down Expand Up @@ -426,7 +431,7 @@ module.exports = function(grunt) {
'mochaTest'
]);
grunt.registerTask('test:nobuild', ['eslint:test', 'connect', 'mocha']);
grunt.registerTask('yui', ['yuidoc:prod', 'minjson']);
grunt.registerTask('yui', ['yuidoc:prod', 'minjson', 'typescript']);
grunt.registerTask('yui:test', ['yuidoc:prod', 'connect', 'mocha:yui']);
grunt.registerTask('default', ['test']);
grunt.registerTask('saucetest', ['connect', 'saucelabs-mocha']);
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,17 @@
"whatwg-fetch": "^2.0.3"
},
"main": "./lib/p5.js",
"types": "./lib/p5.d.ts",

This comment has been minimized.

Copy link
@pflannery

pflannery Jan 21, 2018

@Zalastax Is there a reason why ./lib/p5.global-mode.d.ts wasn't used here? I ask because the global def gives us intellisense for all the global methods like rect, createCanvas etc... The global def also includes p5.d.ts so we still get the p5 class object references too.

Example sketch.js

/// <reference types="p5" />
// cant see intellisense for globals here only p5 object references. i.e. p5.*

setup() {

}

draw() {

}

This comment has been minimized.

Copy link
@Zalastax

Zalastax Jan 21, 2018

Author Member

It's simply pointing to the types that correspond to the "main" field. Someone importing the p5 library when they use npm would want the types to match up. So changing the "types" field can't be done without changing the "main" field, but there might exist alternatives? Can you reference "p5/lib/p5.global-mode.d.ts"? Or perhaps to where they exist on your harddrive? When you find out, please add the solution to the Wiki somewhere. That would be greatly appreciated.

This comment has been minimized.

Copy link
@pflannery

pflannery Jan 21, 2018

@Zalastax

I think people would benefit more from having simple access to intellisense for the globals. Especially as most examples use globals.

The current alternatives I know of are:

1. Tell people they need two references in their files when they use globals and the p5 class. Like this (not ideal)
js /// <reference types="p5" /> /// <reference path="./node_modules/p5/lib/p5.global-mode.d.ts" />
OR
I was over thinking it but having to include the node_module path isn't ideal
2. Include ///<reference path="p5.global-mode.d.ts" /> in the "p5.d.ts" file so people only need to include the one reference in their files.
OR
3. Change "types" to become "./lib/p5.global-mode.d.ts" in package.json (is perfectly legit and works). This would also mean people only need to include one reference in their files.

I think option 3 is the easiest route. But if option 2 do-able then its perfectly fine as well.

This comment has been minimized.

Copy link
@Zalastax

Zalastax Jan 21, 2018

Author Member

I don't think option 2 nor option 3 are doable.
I just tried it out, and if I import p5 const p5 = require("p5"), there's no methods added to the global scope. I really wish there was a way to make this better, but I don't want to tamper on type safety.

So if you download p5 using npm, but then use it in global mode, this is probably as good as we can get it:

/// <reference path="./node_modules/p5/lib/p5.global-mode.d.ts" />

It's unfortunate that there's no way to reference it as "p5/lib/p5.global-mode.d.ts".

Someone who downloads p5 manually can make it a bit nicer, i.e:

/// <reference path="../types/p5.global-mode.d.ts" />

This comment has been minimized.

Copy link
@pflannery

pflannery Jan 21, 2018

@Zalastax I understand now, your looking at consuming p5 using node require rather than from using p5 in the browser.

So happens I've found a solution (at least in vscode)
/// <reference types="p5/lib/p5.global-mode" />

It seems that the "types" field lets us specify the folder inside package

It could probably be improved if "p5.global-mode.d.ts" was renamed to "global.d.ts" so the statement becomes
types="p5/lib/global", or even better if we moved the file and could state something simple like types="p5/browser" as the reference.

This comment has been minimized.

Copy link
@Zalastax

Zalastax Jan 21, 2018

Author Member

I understand now, your looking at consuming p5 using node require rather than from using p5 in the browser.

Yes, or rather in my case, using it with webpack.

So happens I've found a solution

That's great! I tried almost the same, but didn't know you had to leave out .d.ts. Your suggestions make a lot of sense so I've opened an issue requesting that we move the definitions to a more convenient place.

"files": [
"license.txt",
"lib/p5.min.js",
"lib/p5.js",
"lib/addons/p5.sound.js",
"lib/addons/p5.sound.min.js",
"lib/addons/p5.dom.js",
"lib/addons/p5.dom.min.js"
"lib/addons/p5.dom.min.js",
"lib/p5.d.ts",
"lib/p5.global-mode.d.ts"
],
"description": "[![Build Status](https://travis-ci.org/processing/p5.js.svg?branch=master)](https://travis-ci.org/processing/p5.js) [![npm version](https://badge.fury.io/js/p5.svg)](https://www.npmjs.com/package/p5)",
"bugs": {
Expand Down
81 changes: 81 additions & 0 deletions tasks/typescript/emit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
var fs = require('fs');

function shortenDescription(desc) {
var match = desc.match(/^((.|\n)+?\.)\s/);

if (match) {
return match[1];
}
return desc;
}

function createEmitter(filename) {
var indentLevel = 0;
var lastText = '';
var currentSourceFile;
var fd = fs.openSync(filename, 'w');

var emit = function(text) {
var indentation = [];
var finalText;

for (var i = 0; i < indentLevel; i++) {
indentation.push(' ');
}

finalText = indentation.join('') + text + '\n';
fs.writeSync(fd, finalText);

lastText = text;
};

emit.description = function(desc) {
if (!desc) {
return;
}

emit.sectionBreak();
emit('/**');
shortenDescription(desc).split('\n').forEach(function(line) {
emit(' * ' + line);
});
emit(' */');
};

emit.setCurrentSourceFile = function(file) {
if (file !== currentSourceFile) {
currentSourceFile = file;
emit.sectionBreak();
emit('// ' + file);
emit.sectionBreak();
}
};

emit.sectionBreak = function() {
if (lastText !== '' && !/\{$/.test(lastText)) {
emit('');
}
};

emit.getIndentLevel = function() {
return indentLevel;
};

emit.indent = function() {
indentLevel++;
};

emit.dedent = function() {
indentLevel--;
};

emit.close = function() {
fs.closeSync(fd);
};

emit('// This file was auto-generated. Please do not edit it.\n');

return emit;
}

module.exports = createEmitter;
Loading

0 comments on commit 09eed16

Please sign in to comment.