Skip to content
This repository has been archived by the owner on Dec 6, 2022. It is now read-only.

feat: add typedef generation #56

Merged
merged 6 commits into from
Oct 20, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "ipfs"
rvagg marked this conversation as resolved.
Show resolved Hide resolved
}
27 changes: 27 additions & 0 deletions .github/workflows/typecheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
on:
push:
branches:
- master
- main
- default
pull_request:
branches:
- '**'

name: Typecheck
jobs:
check:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x]
Copy link
Member

Choose a reason for hiding this comment

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

any reason to stick with 12.x, can we bump to 14.x to future proof this a bit more?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I honestly wish there was a way to stay whatever the current stable version is, but I can't find a way to do that. Chose 12.x because it's actually newer that 10.x used here and current LTS. Happy to put whatever makes most sense.

Please note that this just runs the typescript not any of the code here.

Copy link
Member

Choose a reason for hiding this comment

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

yeah, so I think 14.x is going to be the best bet here, it's got a much longer life than 12.x ahead of it and is 2 weeks away from being LTS so we may as well start using it in places like this. up to you though.

The labels thing has been an ongoing discussion for a while for setup-node with folks wanting it to copy the nvm style so we could do the same things that we could do with travis, alas no serious movement: actions/setup-node#26

steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm install
- name: Typecheck
uses: gozala/[email protected]
20 changes: 15 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
"main": "src/index.js",
"scripts": {
"lint": "aegir lint",
"build": "aegir build",
"check": "tsc --noEmit --noErrorTruncation",
"build": "npm run build:js && npm run build:types",
"build:js": "aegir build",
"build:types": "tsc --emitDeclarationOnly --declarationDir dist",
"test": "aegir test",
"test:node": "aegir test --target node",
"test:browser": "aegir test --target browser",
Expand Down Expand Up @@ -34,17 +37,24 @@
},
"homepage": "https://github.com/ipld/js-ipld-block#readme",
"devDependencies": {
"aegir": "^25.0.0",
"uint8arrays": "^1.0.0"
"aegir": "^27.0.0",
"uint8arrays": "^1.0.0",
"typescript": "^4.0.3"
},
"dependencies": {
"cids": "^1.0.0",
"class-is": "^1.1.0"
"cids": "^1.0.0"
},
"engines": {
"node": ">=6.0.0",
"npm": ">=3.0.0"
},
"typesVersions": {
"*": {
"*": [
"dist/types/*"
]
}
},
"contributors": [
"David Dias <[email protected]>",
"Volker Mische <[email protected]>",
Expand Down
75 changes: 54 additions & 21 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
'use strict'

const CID = require('cids')
const withIs = require('class-is')

const { version } = require('../package.json')
const blockSymbol = Symbol.for('@ipld/js-ipld-block/block')
const readonly = { writable: false, configurable: false, enumerable: true }

/**
* Represents an immutable block of data that is uniquely referenced with a cid.
*
* @example
* const block = new Block(Uint8Array.from([0, 1, 2, 3]), new CID('...'))
*/
module.exports = class Block {
class Block {
/**
* @constructor
* @param {Uint8Array} data - The data to be stored in the block as a Uint8Array.
* @param {CID} cid - The cid of the data
*/
Expand All @@ -24,46 +26,77 @@ module.exports = class Block {
throw new Error('second argument must be a CID')
}

this._data = data
this._cid = cid
this.data = data
this.cid = cid

Object.defineProperties(this, {
data: readonly,
cid: readonly
})
}

/**
* The data of this block.
*
* @deprecated
* @type {Uint8Array}
*/
get data () {
return this._data
}

set data (val) {
throw new Error('Tried to change an immutable block')
get _data () {
deprecateData()
return this.data
}

/**
* The cid of the data this block represents.
*
* @deprecated
* @type {CID}
*/
get cid () {
return this._cid
get _cid () {
deprecateCID()
return this.cid
}

set cid (val) {
throw new Error('Tried to change an immutable block')
get [Symbol.toStringTag] () {
return 'Block'
}

get [blockSymbol] () {
return true
}

// eslint-disable-next-line valid-jsdoc
/**
* Check if the given value is a Block.
*
* @param {any} other
* @returns {other is Block}
*/
static isBlock (other) { // eslint-disable-line no-unused-vars
// implemented by class-is module
static isBlock (other) {
return Boolean(other && other[blockSymbol])
Copy link
Member

Choose a reason for hiding this comment

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

maybe just return other && other[blockSymbol] === true?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rvagg I'm afraid TS will complain because null && v is null and not a boolean.

Copy link
Member

Choose a reason for hiding this comment

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

urgh, that's kind of gross, return !!other && other[blockSymbol] === true?

}
}

// to trick the typings engine
// https://github.com/ipld/js-ipld-block/pull/55#discussion_r478845002
module.exports = withIs(module.exports, { className: 'Block', symbolName: '@ipld/js-ipld-block/block' })
/**
* @param {RegExp} range
* @param {string} message
* @returns {() => void}
*/
const deprecate = (range, message) => {
let warned = false
return () => {
if (range.test(version)) {
if (!warned) {
warned = true
// eslint-disable-next-line no-console
console.warn(message)
}
} else {
throw new Error(message)
}
}
}

const deprecateCID = deprecate(/^0\.10/, 'block._cid is deprecated and will be removed in the next major release. Use block.cid instead')
const deprecateData = deprecate(/^0\.10/, 'block._data is deprecated and will be removed in the next major release. Use block.data instead')

module.exports = Block
4 changes: 2 additions & 2 deletions test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ describe('block', () => {
expect(
() => { b.data = 'fail' }
).to.throw(
/immutable/
/read.only/
)

expect(
() => { b.cid = 'fail' }
).to.throw(
/immutable/
/read.only/
)
})
})
42 changes: 42 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": false,
"noImplicitAny": true,
"noImplicitThis": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"strictFunctionTypes": false,
"strictNullChecks": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"strict": true,
"alwaysStrict": true,
"esModuleInterop": true,
"target": "ES2018",
"moduleResolution": "node",
"declaration": true,
"declarationMap": true,
"outDir": "dist",
"skipLibCheck": true,
"stripInternal": true,
"resolveJsonModule": true,
"paths": {
"multiformats": [
"src"
]
},
"baseUrl": "."
},
"include": [
"src"
],
"exclude": [
"vendor",
"node_modules"
],
"compileOnSave": false
}