diff --git a/.eslintrc b/.eslintrc index 3ae0c77..8dc3744 100644 --- a/.eslintrc +++ b/.eslintrc @@ -5,14 +5,14 @@ "ecmaVersion": 3, }, "plugins": [ "html", "json" ], - "!extends": "eslint:recommended", + "extends": "eslint:recommended", "rules": { - "no-console": 0, - "no-bitwise": 0, - "curly": 0, "comma-style": [ 2, "last" ], + "comma-dangle": [ 2, "never" ], + "curly": 0, + "no-bitwise": 0, + "no-console": 0, "no-trailing-spaces": 2, - "semi": [ 2, "always" ], - "comma-dangle": [ 2, "never" ] + "semi": [ 2, "always" ] } } diff --git a/.spelling b/.spelling new file mode 100644 index 0000000..20ae537 --- /dev/null +++ b/.spelling @@ -0,0 +1,11 @@ +# adler32.js (C) 2014-present SheetJS -- http://sheetjs.com +SheetJS +31-bit +32-bit +ADLER-32 +UCS-2 +UTF-8 +adler32 +checksum +nodejs +npm diff --git a/.travis.yml b/.travis.yml index c529897..fc97c87 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: node_js node_js: + - "9" - "8" - "7" - "6" diff --git a/Makefile b/Makefile index cf54e13..5229a52 100644 --- a/Makefile +++ b/Makefile @@ -57,6 +57,9 @@ clean-baseline: ## Remove test baselines ## Code Checking +.PHONY: fullint +fullint: lint old-lint tslint flow mdlint ## Run all checks + .PHONY: lint lint: $(TARGET) $(AUXTARGETS) ## Run eslint checks @eslint --ext .js,.njs,.json,.html,.htm $(TARGET) $(AUXTARGETS) $(CMDS) $(HTMLLINT) package.json bower.json @@ -71,6 +74,11 @@ old-lint: $(TARGET) $(AUXTARGETS) ## Run jshint and jscs checks @jscs $(TARGET) $(AUXTARGETS) if [ -e $(CLOSURE) ]; then java -jar $(CLOSURE) $(REQS) $(FLOWTARGET) --jscomp_warning=reportUnknownTypes >/dev/null; fi +.PHONY: tslint +tslint: $(TARGET) ## Run typescript checks + #@npm install dtslint typescript + #@npm run-script dtslint + dtslint types .PHONY: flow flow: lint ## Run flow checker @@ -86,6 +94,12 @@ misc/coverage.html: $(TARGET) test.js coveralls: ## Coverage Test + Send to coveralls.io mocha --require blanket --reporter mocha-lcov-reporter -t 20000 | node ./node_modules/coveralls/bin/coveralls.js +MDLINT=README.md +.PHONY: mdlint +mdlint: $(MDLINT) ## Check markdown documents + alex $^ + mdspell -a -n -x -r --en-us $^ + .PHONY: perf perf: ## Run Performance Tests @bash perf/perf.sh diff --git a/README.md b/README.md index 2504b08..b859cf2 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ $ npm install adler-32 In the browser: ```html - + ``` The browser exposes a variable `ADLER32`. @@ -22,9 +22,8 @@ The browser exposes a variable `ADLER32`. When installed globally, npm installs a script `adler32` that computes the checksum for a specified file or standard input. -The script will manipulate `module.exports` if available (e.g. in a CommonJS -`require` context). This is not always desirable. To prevent the behavior, -define `DO_NOT_EXPORT_ADLER`. +The script will manipulate `module.exports` if available . This is not always +desirable. To prevent the behavior, define `DO_NOT_EXPORT_ADLER`. ## Usage @@ -34,12 +33,12 @@ optional second argument representing the starting "seed" (for running hash). The return value is a signed 32-bit integer. - `ADLER32.buf(byte array or buffer[, seed])` assumes the argument is a sequence - of 8-bit unsigned integers (e.g. nodejs `Buffer` or simple array of ints). + of 8-bit unsigned integers (nodejs `Buffer`, `Uint8Array` or array of bytes). -- `ADLER32.bstr(binary string[, seed])` assumes the argument as a binary string +- `ADLER32.bstr(binary string[, seed])` assumes the argument is a binary string where byte `i` is the low byte of the UCS-2 char: `str.charCodeAt(i) & 0xFF` -- `ADLER32.str(string)` assumes the argument as a standard JS string and +- `ADLER32.str(string)` assumes the argument is a standard JS string and calculates the hash of the UTF-8 encoding. For example: @@ -68,7 +67,7 @@ To run the in-browser tests, run a local server and go to the `ctest` directory. To update the browser artifacts, run `make ctest`. -To generate the bits file, use the `adler32` function from python zlib: +To generate the bits file, use the `adler32` function from python `zlib`: ```python >>> from zlib import adler32 @@ -81,7 +80,7 @@ To generate the bits file, use the `adler32` function from python zlib: 2023497376 ``` -The included `adler32.njs` script can process files or stdin: +The included `adler32.njs` script can process files or standard input: ```bash $ echo "this is a test" > t.txt @@ -89,7 +88,7 @@ $ bin/adler32.njs t.txt 726861088 ``` -For comparison, the included `adler32.py` script uses python zlib: +For comparison, the included `adler32.py` script uses python `zlib`: ```bash $ bin/adler32.py t.txt @@ -101,7 +100,7 @@ $ bin/adler32.py t.txt `make perf` will run algorithmic performance tests (which should justify certain decisions in the code). -Bit twiddling is much faster than taking the mod on Safari and older Firefoxes. +Bit twiddling is much faster than taking the mod in Safari and Firefox browsers. Instead of taking the literal mod 65521, it is faster to keep it in the integers by bit-shifting: `65536 ~ 15 mod 65521` so for nonnegative integer `a`: @@ -122,7 +121,7 @@ F[255] (* bstr: x \[Element] Integers && 1 <= x <= 3854 *) F[127] (* ascii: x \[Element] Integers && 1 <= x <= 5321 *) ``` -Subtract up to 4 elements for the unicode case. +Subtract up to 4 elements for the Unicode case. ## License diff --git a/adler32.flow.js b/adler32.flow.js index fae0e23..7bc16c0 100644 --- a/adler32.flow.js +++ b/adler32.flow.js @@ -1,32 +1,34 @@ /* adler32.js (C) 2014-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ /*exported ADLER32 */ -var ADLER32; -/*:: declare var DO_NOT_EXPORT_ADLER: any; */ -/*:: declare var define: any; */ -(function (factory) { +/*:: declare var DO_NOT_EXPORT_ADLER:?boolean; */ +/*:: declare function define(cb:()=>any):void; */ +var ADLER32/*:ADLER32Module*/; +(function (factory/*:(a:any)=>void*/)/*:void*/ { /*jshint ignore:start */ + /*eslint-disable */ if(typeof DO_NOT_EXPORT_ADLER === 'undefined') { if('object' === typeof exports) { factory(exports); } else if ('function' === typeof define && define.amd) { define(function () { - var module = {}; + var module/*:ADLER32Module*/ = /*::(*/{}/*:: :any)*/; factory(module); return module; }); } else { - factory(ADLER32 = {}); + factory(ADLER32 = /*::(*/{}/*:: :any)*/); } } else { - factory(ADLER32 = {}); + factory(ADLER32 = /*::(*/{}/*:: :any)*/); } + /*eslint-enable */ /*jshint ignore:end */ -}(function(ADLER32) { -ADLER32.version = '1.1.0'; +}(function(ADLER32/*:ADLER32Module*/) { +ADLER32.version = '1.2.0'; /*:: type ADLER32Type = number; -type ABuf = Array | Buffer; +type ABuf = Array | Buffer | Uint8Array; */ /*# consult README.md for the magic number */ /*# charCodeAt is the best approach for binary strings */ @@ -90,7 +92,10 @@ function adler32_str(str/*:string*/, seed/*:?ADLER32Type*/)/*:ADLER32Type*/ { } return ((b%65521) << 16) | (a%65521); } +// $FlowIgnore ADLER32.bstr = adler32_bstr; +// $FlowIgnore ADLER32.buf = adler32_buf; +// $FlowIgnore ADLER32.str = adler32_str; })); diff --git a/adler32.js b/adler32.js index 7dfff51..ad6bfb7 100644 --- a/adler32.js +++ b/adler32.js @@ -4,6 +4,7 @@ var ADLER32; (function (factory) { /*jshint ignore:start */ + /*eslint-disable */ if(typeof DO_NOT_EXPORT_ADLER === 'undefined') { if('object' === typeof exports) { factory(exports); @@ -19,9 +20,10 @@ var ADLER32; } else { factory(ADLER32 = {}); } + /*eslint-enable */ /*jshint ignore:end */ }(function(ADLER32) { -ADLER32.version = '1.1.0'; +ADLER32.version = '1.2.0'; function adler32_bstr(bstr, seed) { var a = 1, b = 0, L = bstr.length, M = 0; if(typeof seed === 'number') { a = seed & 0xFFFF; b = seed >>> 16; } @@ -81,7 +83,10 @@ function adler32_str(str, seed) { } return ((b%65521) << 16) | (a%65521); } +// $FlowIgnore ADLER32.bstr = adler32_bstr; +// $FlowIgnore ADLER32.buf = adler32_buf; +// $FlowIgnore ADLER32.str = adler32_str; })); diff --git a/bin/adler32.njs b/bin/adler32.njs index fa6b075..2e31986 100755 --- a/bin/adler32.njs +++ b/bin/adler32.njs @@ -1,6 +1,8 @@ #!/usr/bin/env node /* adler32.js (C) 2014-present SheetJS -- http://sheetjs.com */ +/* eslint-env node */ /* vim: set ts=2 ft=javascript: */ +/*jshint node:true */ var X/*:ADLER32Module*/; try { X = require('../'); } catch(e) { X = require('adler-32'); } diff --git a/bits/00_header.js b/bits/00_header.js index cdbabfe..f5899d7 100644 --- a/bits/00_header.js +++ b/bits/00_header.js @@ -1,25 +1,27 @@ /* adler32.js (C) 2014-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ /*exported ADLER32 */ -var ADLER32; -/*:: declare var DO_NOT_EXPORT_ADLER: any; */ -/*:: declare var define: any; */ -(function (factory) { +/*:: declare var DO_NOT_EXPORT_ADLER:?boolean; */ +/*:: declare function define(cb:()=>any):void; */ +var ADLER32/*:ADLER32Module*/; +(function (factory/*:(a:any)=>void*/)/*:void*/ { /*jshint ignore:start */ + /*eslint-disable */ if(typeof DO_NOT_EXPORT_ADLER === 'undefined') { if('object' === typeof exports) { factory(exports); } else if ('function' === typeof define && define.amd) { define(function () { - var module = {}; + var module/*:ADLER32Module*/ = /*::(*/{}/*:: :any)*/; factory(module); return module; }); } else { - factory(ADLER32 = {}); + factory(ADLER32 = /*::(*/{}/*:: :any)*/); } } else { - factory(ADLER32 = {}); + factory(ADLER32 = /*::(*/{}/*:: :any)*/); } + /*eslint-enable */ /*jshint ignore:end */ -}(function(ADLER32) { +}(function(ADLER32/*:ADLER32Module*/) { diff --git a/bits/01_version.js b/bits/01_version.js index 3f19edd..b69c5d4 100644 --- a/bits/01_version.js +++ b/bits/01_version.js @@ -1 +1 @@ -ADLER32.version = '1.1.0'; +ADLER32.version = '1.2.0'; diff --git a/bits/10_types.js b/bits/10_types.js index dbd3846..2f67be7 100644 --- a/bits/10_types.js +++ b/bits/10_types.js @@ -1,4 +1,4 @@ /*:: type ADLER32Type = number; -type ABuf = Array | Buffer; +type ABuf = Array | Buffer | Uint8Array; */ diff --git a/bits/90_exports.js b/bits/90_exports.js index ac0bcde..57e1b69 100644 --- a/bits/90_exports.js +++ b/bits/90_exports.js @@ -1,3 +1,6 @@ +// $FlowIgnore ADLER32.bstr = adler32_bstr; +// $FlowIgnore ADLER32.buf = adler32_buf; +// $FlowIgnore ADLER32.str = adler32_str; diff --git a/ctest/adler32.js b/ctest/adler32.js index 7dfff51..ad6bfb7 100644 --- a/ctest/adler32.js +++ b/ctest/adler32.js @@ -4,6 +4,7 @@ var ADLER32; (function (factory) { /*jshint ignore:start */ + /*eslint-disable */ if(typeof DO_NOT_EXPORT_ADLER === 'undefined') { if('object' === typeof exports) { factory(exports); @@ -19,9 +20,10 @@ var ADLER32; } else { factory(ADLER32 = {}); } + /*eslint-enable */ /*jshint ignore:end */ }(function(ADLER32) { -ADLER32.version = '1.1.0'; +ADLER32.version = '1.2.0'; function adler32_bstr(bstr, seed) { var a = 1, b = 0, L = bstr.length, M = 0; if(typeof seed === 'number') { a = seed & 0xFFFF; b = seed >>> 16; } @@ -81,7 +83,10 @@ function adler32_str(str, seed) { } return ((b%65521) << 16) | (a%65521); } +// $FlowIgnore ADLER32.bstr = adler32_bstr; +// $FlowIgnore ADLER32.buf = adler32_buf; +// $FlowIgnore ADLER32.str = adler32_str; })); diff --git a/ctest/fixtures.js b/ctest/fixtures.js index 7f11a14..19d98b8 100644 --- a/ctest/fixtures.js +++ b/ctest/fixtures.js @@ -22,13 +22,10 @@ var bits = [ ]; if(typeof module !== "undefined") module.exports = bits; /*:: -type ArrayLike = any; -type Stringifier = {(d:ArrayLike):string}; - declare class ADLER32Module { - bstr(s:string, seed:?ADLER32Type):ADLER32Type; - buf(b:ABuf, seed:?ADLER32Type):ADLER32Type; - str(s:string, seed:?ADLER32Type):ADLER32Type; + bstr(s:string, seed?:ADLER32Type):ADLER32Type; + buf(b:ABuf, seed?:ADLER32Type):ADLER32Type; + str(s:string, seed?:ADLER32Type):ADLER32Type; version:string; }; */ diff --git a/demo/browser.flow.js b/demo/browser.flow.js index 3c1ec5e..5da61de 100644 --- a/demo/browser.flow.js +++ b/demo/browser.flow.js @@ -1,5 +1,6 @@ /*jshint browser:true */ -/*global ADLER32, console */ +/*eslint-env browser */ +/*global ADLER32, console, Uint8Array */ /*:: declare var ADLER32: ADLER32Module; */ var X = ADLER32; @@ -17,6 +18,10 @@ function is_defined(val/*:any*/, keys/*:Array*/)/*:boolean*/ { } /*# buffer to string; IE String.fromCharCode.apply limit, manual chunk */ +/*:: +type ArrayLike = any; +type Stringifier = {(d:ArrayLike):string}; +*/ function make_chunk_buf_to_str(BType/*:function*/)/*:Stringifier*/ { return function(data/*:any*/)/*:string*/ { var o = "", l = 0, w = 10240, L = data.byteLength/w; @@ -66,7 +71,7 @@ var readcb = function(e/*:Event*/) { console_log("onload", new Date(), rABS, false); var target/*:FileReader*/ = (e.target/*:any*/); var data = target.result; - var val/*:ADLER32Type*/ = rABS ? X.bstr(data) : X.str(bstrify(data)); + var val/*:ADLER32Type*/ = rABS ? X.bstr(/*::(*/data/*:: :any)*/) : X.str(bstrify(data)); process_value(val); }; diff --git a/demo/browser.js b/demo/browser.js index f7dcf00..870d11c 100644 --- a/demo/browser.js +++ b/demo/browser.js @@ -1,5 +1,6 @@ /*jshint browser:true */ -/*global ADLER32, console */ +/*eslint-env browser */ +/*global ADLER32, console, Uint8Array */ var X = ADLER32; function console_log() { if(typeof console !== 'undefined') console.log.apply(console, [].slice.call(arguments)); } diff --git a/index.html b/index.html index b5d43d2..91ac8b8 100644 --- a/index.html +++ b/index.html @@ -45,6 +45,7 @@ Use readAsBinaryString: (when available)