Skip to content
This repository was archived by the owner on Dec 1, 2024. It is now read-only.

Conversation

@MeirionHughes
Copy link
Member

@MeirionHughes MeirionHughes commented Sep 6, 2017

bit of a fiddly one this. basically it is typed to that you can argument the abstract-leveldown store type and then infer:

  • the options you need to pass through to levelup(store, ...)
  • the put, get, delete, batch options you use with levelup()

example typescript.

import * as levelup from 'levelup';
import * as leveldown from 'leveldown';

let db = levelup(leveldown('./db'));

async function main() {
  await db.put("hello", new Buffer([1, 2, 3, 4]), );
  await db.get("hello", ).then(console.log);

  await db.batch()
    .put("foo", new Buffer([1]))
    .put("bar", new Buffer([2]))
    .put("ray", new Buffer([3]))
    .del("hello")
    .write();

  await new Promise(r => {
    db.createReadStream({
      limit: 2
    }).on("data", (data) => {
      console.log(data);
    }).on("end", r);
  });
}
  • could do with a review to ensure you want to go this route the the type generics.
  • probably worth adding types to abstract-leveldown and using them here.
  • add missing typings. i.e. levelup errors and double-check against docs

@MeirionHughes
Copy link
Member Author

MeirionHughes commented Sep 6, 2017

the plugin augmentation:

function down(): levelup.AbstractDown<{ fast: boolean }, any, any, any, { foo: boolean }> {
  return undefined;
}

function plugin<P, G, D, B, O>(
  store: levelup.AbstractDown<P, G, D, B, O>
): levelup.AbstractDown<P & {slow: boolean}, any, any, any, { foo: boolean }> {
  return undefined;
}

let db = levelup(plugin(down()));

db.put("hello", "world", { fast: true }, ()=>{});

TSError: ⨯ Unable to compile TypeScript
Argument of type '{ fast: true; }' is not assignable to parameter of type '{ fast: boolean; } & { slow: boolean; }
Type '{ fast: true; }' is not assignable to type '{ slow: boolean; }'.
Property 'slow' is missing in type '{ fast: true; }'. (2345)

@ralphtheninja
Copy link
Member

I don't feel that I'm qualified to review this. Maybe someone can fill in here?

@MeirionHughes
Copy link
Member Author

MeirionHughes commented Sep 6, 2017

main issue is while the typescript compiler is able to correctly infer and check the types after they've been augmented by any plugins you use, vscode intellisense is not as able keep up and gives up trying to work out the options type.

basically, with this approach you'd currently not get intellisense on the levelup ctor options.

There is an alternative way to do the typings (so they are extendable) but it requires using a global definition - so it would be the same for every instance of levelup.

@juliangruber
Copy link
Member

I'm not qualified to review this either. Instead, would it be possible to add a test suite for this?

@MeirionHughes
Copy link
Member Author

@juliangruber I could add a test to ensure the typescript compiler is happy / unhappy with common use-cases.

@juliangruber
Copy link
Member

Would it be possible to run the whole test suite through typescript actually?

@vweevers
Copy link
Member

vweevers commented Sep 8, 2017

Would it be possible to run the whole test suite through typescript actually?

Mind blown

@MeirionHughes
Copy link
Member Author

hmm not sure; I've not used the test runner you use. If you'd gone with mocha, it would have been a minor cli argument to switch to typescript. :)

@vweevers
Copy link
Member

vweevers commented Sep 8, 2017

The tests (individually) can be run with node some-test.js, so maybe replace node with ts-node?

And to run the whole suite, something like: ts-node node_modules/tape/bin/tape test/*-test.js (to start).

@ralphtheninja
Copy link
Member

Would it be possible to run the whole test suite through typescript actually?

Brilliant idea if we can get that to work

@MeirionHughes
Copy link
Member Author

MeirionHughes commented Sep 10, 2017

It very nearly works; unfortunately typescript doesn't understand util.inherits so it doesn't think LevelUP has emit and, as a result, gives out errors.

You'd need to have LevelUP be a class for typescript to know it inherits emit.

I can trick typescript with:

LevelUP.prototype.emit = EventEmitter.prototype.emit
LevelUP.prototype.once = EventEmitter.prototype.once

inherits(LevelUP, EventEmitter);

@ralphtheninja
Copy link
Member

@MeirionHughes Maybe it's possible to provide that information via typescript definitions? Maybe not ideal but as a workaround.

@MeirionHughes
Copy link
Member Author

I've found a workaround (see edit above). Its working. I'm just fixing typing errors now.

.travis.yml Outdated
- export JOBS=max

before_script:
- npm install typescript ts-node -g
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to add these as devDependencies instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done. :)

@ralphtheninja
Copy link
Member

ralphtheninja commented Sep 10, 2017

@MeirionHughes Mind updating level-errors to e.g. ~1.1.0?

Nevermind, I pulled that in. Should be enough to rebase this PR onto latest master.

@ralphtheninja
Copy link
Member

How about releasing rc2 once this is merged?

@ralphtheninja
Copy link
Member

Something is up with the tests. I can reproduce locally.

@MeirionHughes
Copy link
Member Author

yeah; error typing is wrong was missing the 2nd parameter for cause; patched Level/errors#9

Test also fails (only on travis) right at the end saying things are out of order.

@MeirionHughes
Copy link
Member Author

@ralphtheninja I'm not sure about the order errors. If you run node ./test/ts-test.js it will happily run and return.

@ralphtheninja
Copy link
Member

ralphtheninja commented Sep 10, 2017

@ralphtheninja I'm not sure about the order errors. If you run node ./test/ts-test.js it will happily run and return.

It fails for me. Are you sure you don't have a globally installed ts-node and typescript?

@ralphtheninja
Copy link
Member

Actually, I think it would be easier if you just added a script for simply running ts-node instead of having a test/ts-test.js that in turn does that. We also get rid of the check for not running the tests on ts-test.js itself.

@ralphtheninja
Copy link
Member

Or maybe that will cause problems on windows (e.g. a for loop in the shell running ts-node test/$file-test.js)

@ralphtheninja
Copy link
Member

@MeirionHughes I'm experimenting locally a bit, I can make a PR on top of this PR if you like.

@ralphtheninja ralphtheninja mentioned this pull request Sep 10, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants