From 252bec0ad260f6778e46ce06a390a8d28aa39548 Mon Sep 17 00:00:00 2001 From: Kevin Jahns Date: Thu, 13 Jul 2017 17:42:21 +0200 Subject: [PATCH] implemented binary encoding for all basic structs --- package-lock.json | 592 +++++++++++++++++++++++++++++++++++++++++- package.json | 5 +- rollup.test.js | 6 +- src/Encoding.js | 102 ++++++++ src/Struct.js | 151 ++++++++++- test/encode-decode.js | 221 ++++++++++++++++ 6 files changed, 1056 insertions(+), 21 deletions(-) create mode 100644 src/Encoding.js create mode 100644 test/encode-decode.js diff --git a/package-lock.json b/package-lock.json index 6aaa92f2..6878d781 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3,6 +3,12 @@ "version": "13.0.0-4", "lockfileVersion": 1, "dependencies": { + "accepts": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", + "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=", + "dev": true + }, "acorn": { "version": "4.0.13", "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", @@ -63,8 +69,19 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz", "integrity": "sha1-o+Uvo5FoyCX/V7AkgSbOWo/5VQc=", - "dev": true, - "optional": true + "dev": true + }, + "apache-crypt": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/apache-crypt/-/apache-crypt-1.2.1.tgz", + "integrity": "sha1-1vxyqm0n2ZyVqU/RiNcx7v/6Zjw=", + "dev": true + }, + "apache-md5": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/apache-md5/-/apache-md5-1.1.2.tgz", + "integrity": "sha1-7klza2ObTxCLbp5ibG2pkwa0FpI=", + "dev": true }, "argparse": { "version": "1.0.9", @@ -90,6 +107,12 @@ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", @@ -130,8 +153,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true, - "optional": true + "dev": true }, "babel-cli": { "version": "6.24.1", @@ -499,12 +521,29 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "basic-auth": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz", + "integrity": "sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ=", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=", + "dev": true + }, "binary-extensions": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.8.0.tgz", "integrity": "sha1-SOyNFt9Dd+rl+liEaCSAr02Vx3Q=", - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.8", @@ -556,6 +595,20 @@ "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", "dev": true }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + } + } + }, "center-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", @@ -586,8 +639,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "optional": true + "dev": true }, "circular-json": { "version": "0.3.1", @@ -625,6 +677,12 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, "commander": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.10.0.tgz", @@ -701,6 +759,26 @@ } } }, + "connect": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.5.1.tgz", + "integrity": "sha1-bTDXpjx/FwhXprOqazY9lz3KWI4=", + "dev": true, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + } + } + }, "contains-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", @@ -725,6 +803,24 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "cors": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.3.tgz", + "integrity": "sha1-TPeOHSMymnSWsvwiJbd8pbteuAI=", + "dev": true + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true + }, + "cutest": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/cutest/-/cutest-0.1.9.tgz", + "integrity": "sha512-bRyVi9vWknRWw+wIx0hhsCJKnsvRsB3Jmssl0zlFrKyqrYeBPpMKoZItpl7nziZi9ZqrgYoGo21fWKvnJIo8Dw==", + "dev": true + }, "d": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", @@ -778,6 +874,18 @@ "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", "dev": true }, + "depd": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz", + "integrity": "sha1-4b2Cxqq2ztlluXuIsX7T5SjKGMM=", + "dev": true + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, "detect-indent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", @@ -790,12 +898,36 @@ "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", "dev": true }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "encodeurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", + "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=", + "dev": true + }, "error-ex": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "dev": true }, + "error-stack-parser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.1.tgz", + "integrity": "sha1-oyArj7AxFKqbQKDjZp5IsrZaAQo=", + "dev": true + }, "es-abstract": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.7.0.tgz", @@ -844,6 +976,12 @@ "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", "dev": true }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -990,12 +1128,24 @@ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, + "etag": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.0.tgz", + "integrity": "sha1-b2Ma7zNtbEY2K1F2QETOIWvjwFE=", + "dev": true + }, "event-emitter": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", "dev": true }, + "event-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "dev": true + }, "exit-hook": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", @@ -1044,6 +1194,12 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "faye-websocket": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", + "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", + "dev": true + }, "figures": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", @@ -1068,6 +1224,26 @@ "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", "dev": true }, + "finalhandler": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.5.1.tgz", + "integrity": "sha1-LEANjUUwk1vCMlScX6OF7Afeb80=", + "dev": true, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + } + } + }, "find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", @@ -1104,6 +1280,18 @@ "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", "dev": true }, + "fresh": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz", + "integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44=", + "dev": true + }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", + "dev": true + }, "fs-exists-sync": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", @@ -1893,6 +2081,24 @@ "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", "dev": true }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "dev": true + }, + "http-auth": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/http-auth/-/http-auth-3.1.3.tgz", + "integrity": "sha1-lFz63WZSHq+PfISRPTd9exXyTjE=", + "dev": true + }, + "http-errors": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.1.tgz", + "integrity": "sha1-X4uO2YrKVFZWv1cplzh/kEpyIlc=", + "dev": true + }, "ignore": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.3.tgz", @@ -1905,6 +2111,12 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -1951,8 +2163,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "optional": true + "dev": true }, "is-buffer": { "version": "1.1.5", @@ -1960,6 +2171,12 @@ "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", "dev": true }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true + }, "is-callable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", @@ -2086,6 +2303,12 @@ "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", "dev": true }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, "is-valid-glob": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz", @@ -2098,6 +2321,12 @@ "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", "dev": true }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -2182,6 +2411,20 @@ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true }, + "live-server": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/live-server/-/live-server-1.2.0.tgz", + "integrity": "sha1-RJhkS7+Bpm8Y3Y3/3vYcTBw3TKM=", + "dev": true, + "dependencies": { + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + } + } + }, "load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", @@ -2226,24 +2469,74 @@ "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", "dev": true }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true + }, "magic-string": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.19.1.tgz", "integrity": "sha1-FNdoATyvLsj96hakmvgvw3fnUgE=", "dev": true }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", + "dev": true + }, "matched": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/matched/-/matched-0.4.4.tgz", "integrity": "sha1-Vte36xgDPwz5vFLrIJD6x9weifo=", "dev": true }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, "micromatch": { "version": "2.3.11", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true }, + "mime": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", + "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=", + "dev": true + }, + "mime-db": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz", + "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=", + "dev": true + }, + "mime-types": { + "version": "2.1.15", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz", + "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -2262,6 +2555,12 @@ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true }, + "morgan": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.8.2.tgz", + "integrity": "sha1-eErHc05KRTqcbm6GgKkyknXItoc=", + "dev": true + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -2286,6 +2585,18 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "dev": true + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true + }, "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", @@ -2322,6 +2633,18 @@ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", "dev": true }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true + }, + "on-headers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", + "dev": true + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2334,6 +2657,12 @@ "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", "dev": true }, + "opn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.1.0.tgz", + "integrity": "sha512-iPNl7SyM8L30Rm1sjGdLLheyHVw5YXVfi3SKWJzBI7efxRwHojfRFjwE/OLM6qp9xJYMgab8WicTU1cPoY+Hpg==", + "dev": true + }, "optionator": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", @@ -2396,6 +2725,12 @@ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", "dev": true }, + "parseurl": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz", + "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY=", + "dev": true + }, "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", @@ -2420,6 +2755,18 @@ "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", "dev": true }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true + }, + "pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "dev": true + }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", @@ -2506,6 +2853,12 @@ "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", "dev": true }, + "proxy-middleware": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz", + "integrity": "sha1-o/3xvvtzD5UZZYcqwvYHTGFHelY=", + "dev": true + }, "randomatic": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", @@ -2534,6 +2887,38 @@ } } }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", + "dev": true + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "dependencies": { + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true + }, "readable-stream": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", @@ -2544,8 +2929,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", - "dev": true, - "optional": true + "dev": true }, "readline2": { "version": "1.0.1", @@ -2559,6 +2943,12 @@ "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "dev": true }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true + }, "regenerate": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz", @@ -2793,6 +3183,26 @@ "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "dev": true }, + "send": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/send/-/send-0.15.3.tgz", + "integrity": "sha1-UBP5+ZAj31DRvZiSwZ4979HVMwk=", + "dev": true, + "dependencies": { + "debug": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", + "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", + "dev": true + } + } + }, + "serve-index": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.0.tgz", + "integrity": "sha1-0rKA/FYNYW7oG0i/D6gqvtJIXOc=", + "dev": true + }, "set-getter": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz", @@ -2803,8 +3213,13 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true, - "optional": true + "dev": true + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", + "dev": true }, "shelljs": { "version": "0.7.8", @@ -2812,6 +3227,12 @@ "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", "dev": true }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", @@ -2842,12 +3263,60 @@ "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", "dev": true }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "dev": true + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "stack-generator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.1.tgz", + "integrity": "sha1-s32LDZoqblLAbMjhhfmPGZ+2OAQ=", + "dev": true + }, + "stackframe": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.0.3.tgz", + "integrity": "sha1-/mSrILFw5M5JBEsSbBGd+g5dx8w=", + "dev": true + }, + "stacktrace-gps": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-3.0.1.tgz", + "integrity": "sha1-Hm9Jl4QdK1vaurnmEX6WXrvmQoY=", + "dev": true + }, + "stacktrace-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-2.0.0.tgz", + "integrity": "sha1-d2ymRqlbxsayuQd2U2p/xyxt21g=", + "dev": true + }, "standard": { "version": "10.0.2", "resolved": "https://registry.npmjs.org/standard/-/standard-10.0.2.tgz", @@ -2868,6 +3337,18 @@ } } }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + }, + "stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "dev": true + }, "string_decoder": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", @@ -2880,6 +3361,16 @@ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true }, + "string.fromcodepoint": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string.fromcodepoint/-/string.fromcodepoint-0.2.1.tgz", + "integrity": "sha1-jZeDM8C8klOPUPOD5IiPPlYZ1lM=" + }, + "string.prototype.codepointat": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.0.tgz", + "integrity": "sha1-aybpvTr8qnvjtCabUm3huCAArHg=" + }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -2892,6 +3383,20 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "dependencies": { + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + } + } + }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -2972,6 +3477,12 @@ "integrity": "sha1-yWPc8DciiS7FnLpWnpQLcZVNFyk=", "dev": true }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, "trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", @@ -3015,30 +3526,83 @@ "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", "dev": true }, + "unix-crypt-td-js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unix-crypt-td-js/-/unix-crypt-td-js-1.0.0.tgz", + "integrity": "sha1-HAgkFQSBvHoB1J6Y8exmjYJBLzs=", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, "user-home": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", "dev": true }, + "utf-8": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/utf-8/-/utf-8-1.0.0.tgz", + "integrity": "sha1-QpwJ+xrDLOuvVllh7aSMs/RSIZc=" + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "utils-merge": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", + "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=", + "dev": true + }, + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", + "dev": true + }, "v8flags": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", "dev": true }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true + }, + "vary": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.1.tgz", + "integrity": "sha1-Z1Neu2lMHVIldFeYRmUyP1h+jTc=", + "dev": true + }, "vlq": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.2.tgz", "integrity": "sha1-4xbVJXtAuGu0PLjV/qXX9U1rDKE=", "dev": true }, + "websocket-driver": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", + "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", + "dev": true + }, + "websocket-extensions": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.1.tgz", + "integrity": "sha1-domUmcGEtu91Q3fC27DNbLVdKec=", + "dev": true + }, "which": { "version": "1.2.14", "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", diff --git a/package.json b/package.json index 4e0df5a9..3435a6b2 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "module": "./src/y.js", "scripts": { "test": "npm run lint", + "debug": "concurrently 'rollup -wc rollup.test.js' 'cutest-serve y.test.js -o'", "lint": "standard", "dist": "rollup -c rollup.browser.js; rollup -c rollup.node.js", "postversion": "npm run dist", @@ -49,6 +50,7 @@ "babel-preset-latest": "^6.24.1", "chance": "^1.0.9", "concurrently": "^3.4.0", + "cutest": "^0.1.9", "rollup-plugin-babel": "^2.7.1", "rollup-plugin-commonjs": "^8.0.2", "rollup-plugin-inject": "^2.0.0", @@ -61,6 +63,7 @@ "tag-dist-files": "^0.1.6" }, "dependencies": { - "debug": "^2.6.8" + "debug": "^2.6.8", + "utf-8": "^1.0.0" } } diff --git a/rollup.test.js b/rollup.test.js index 8ff10e53..c4df1298 100644 --- a/rollup.test.js +++ b/rollup.test.js @@ -3,8 +3,8 @@ import commonjs from 'rollup-plugin-commonjs' import multiEntry from 'rollup-plugin-multi-entry' export default { - entry: 'tests/*.js', - moduleName: 'y-array-tests', + entry: 'test/*', + moduleName: 'y-tests', format: 'umd', plugins: [ nodeResolve({ @@ -15,6 +15,6 @@ export default { commonjs(), multiEntry() ], - dest: 'y-array.test.js', + dest: 'y.test.js', sourceMap: true } diff --git a/src/Encoding.js b/src/Encoding.js new file mode 100644 index 00000000..b1669c55 --- /dev/null +++ b/src/Encoding.js @@ -0,0 +1,102 @@ +import utf8 from 'utf-8' + +const bits7 = 0b1111111 + +export class BinaryLength { + constructor () { + this.length = 0 + } + writeUint8 (num) { + this.length++ + } + writeVarUint (num) { + while (num >= 0b10000000) { + this.length++ + num >>= 7 + } + this.length++ + } + writeVarString (str) { + let len = utf8.setBytesFromString(str).length + this.writeVarUint(len) + this.length += len + } + writeOpID (id) { + this.writeVarUint(id[0]) + this.writeVarUint(id[1]) + } +} + +export class BinaryEncoder { + constructor (binaryLength) { + this.dataview = new DataView(new ArrayBuffer(binaryLength.length)) + this.pos = 0 + } + writeUint8 (num) { + this.dataview.setUint8(this.pos++, num) + } + writeVarUint (num) { + while (num >= 0b10000000) { + this.dataview.setUint8(this.pos++, 0b10000000 | (bits7 & num)) + num >>= 7 + } + this.dataview.setUint8(this.pos++, bits7 & num) + } + writeVarString (str) { + let bytes = utf8.setBytesFromString(str) + let len = bytes.length + this.writeVarUint(len) + for (let i = 0; i < len; i++) { + this.dataview.setUint8(this.pos++, bytes[i]) + } + } + writeOpID (id) { + this.writeVarUint(id[0]) + this.writeVarUint(id[1]) + } +} + +export class BinaryDecoder { + constructor (dataview) { + this.dataview = dataview + this.pos = 0 + } + skip8 () { + this.pos++ + } + skip16 () { + this.pos += 2 + } + skip32 () { + this.pos += 4 + } + skipVar () { + while (this.dataview.getUint8(this.pos++) >= 1 << 7) { } + } + readUint8 () { + return this.dataview.getUint8(this.pos++) + } + readVarUint () { + let num = 0 + let len = 0 + while (true) { + let r = this.dataview.getUint8(this.pos++) + num = num | ((r & bits7) << len) + len += 7 + if (r < 1 << 7) { + return num + } + } + } + readVarString () { + let len = this.readVarUint() + let bytes = new Array(len) + for (let i = 0; i < len; i++) { + bytes[i] = this.dataview.getUint8(this.pos++) + } + return utf8.getStringFromBytes(bytes) + } + readOpID () { + return [this.readVarUint(), this.readVarUint()] + } +} diff --git a/src/Struct.js b/src/Struct.js index 1b6581d7..a766e4de 100644 --- a/src/Struct.js +++ b/src/Struct.js @@ -1,5 +1,7 @@ -/* @flow */ -'use strict' +const CDELETE = 0 +const CINSERT = 1 +const CLIST = 2 +const CMAP = 3 /* An operation also defines the structure of a type. This is why operation and @@ -36,6 +38,19 @@ export default function extendStruct (Y) { struct: 'Delete' } }, + binaryEncode: function (encoder, op) { + encoder.writeUint8(CDELETE) + encoder.writeOpID(op.target) + encoder.writeVarUint(op.length || 0) + }, + binaryDecode: function (decoder) { + decoder.skip8() + return { + target: decoder.readOpID(), + length: decoder.readVarUint(), + struct: 'Delete' + } + }, requiredOps: function (op) { return [] // [op.target] }, @@ -77,6 +92,91 @@ export default function extendStruct (Y) { return e }, + binaryEncode: function (encoder, op) { + encoder.writeUint8(CINSERT) + // compute info property + let contentIsText = op.content != null && op.content.every(c => typeof c === 'string' && c.length === 1) + let originIsLeft = Y.utils.compareIds(op.left, op.origin) + let info = + (op.parentSub != null ? 1 : 0) | + (op.opContent != null ? 2 : 0) | + (contentIsText ? 4 : 0) | + (originIsLeft ? 8 : 0) | + (op.left != null ? 16 : 0) | + (op.right != null ? 32 : 0) | + (op.origin != null ? 64 : 0) + encoder.writeUint8(info) + encoder.writeOpID(op.id) + encoder.writeOpID(op.parent) + if (info & 16) { + encoder.writeOpID(op.left) + } + if (info & 32) { + encoder.writeOpID(op.right) + } + if (!originIsLeft && info & 64) { + encoder.writeOpID(op.origin) + } + if (info & 1) { + // write parentSub + encoder.writeVarString(op.parentSub) + } + if (info & 2) { + // write opContent + encoder.writeOpID(op.opContent) + } else if (info & 4) { + // write text + encoder.writeVarString(op.content.join('')) + } else { + // convert to JSON and write + encoder.writeVarString(JSON.stringify(op.content)) + } + }, + binaryDecode: function (decoder) { + let op = { + struct: 'Insert' + } + decoder.skip8() + // get info property + let info = decoder.readUint8() + + op.id = decoder.readOpID() + op.parent = decoder.readOpID() + if (info & 16) { + op.left = decoder.readOpID() + } else { + op.left = null + } + if (info & 32) { + op.right = decoder.readOpID() + } else { + op.right = null + } + if (info & 8) { + // origin is left + op.origin = op.left + } else if (info & 64) { + op.origin = decoder.readOpID() + } else { + op.origin = null + } + if (info & 1) { + // has parentSub + op.parentSub = decoder.readVarString() + } + if (info & 2) { + // has opContent + op.opContent = decoder.readOpID() + } else if (info & 4) { + // has pure text content + op.content = decoder.readVarString().split('') + } else { + // has mixed content + let s = decoder.readVarString() + op.content = JSON.parse(s) + } + return op + }, requiredOps: function (op) { var ids = [] if (op.left != null) { @@ -300,6 +400,8 @@ export default function extendStruct (Y) { type: op.type } if (op.requires != null) { + debugger // TODO: this is used. adapt binarEncode/Decode!! + console.warn('Note to myself: this is used. adapt binarEncode/Decode!!') e.requires = op.requires } if (op.info != null) { @@ -307,6 +409,26 @@ export default function extendStruct (Y) { } return e }, + binaryEncode: function (encoder, op) { + encoder.writeUint8(CLIST) + encoder.writeOpID(op.id) + encoder.writeVarString(op.type) + let info = op.info != null ? JSON.stringify(op.info) : '' + encoder.writeVarString(info) + }, + binaryDecode: function (decoder) { + decoder.skip8() + let op = { + id: decoder.readOpID(), + type: decoder.readVarString(), + struct: 'List' + } + let info = decoder.readVarString() + if (info.length > 0) { + op.info = JSON.parse(info) + } + return op + }, requiredOps: function () { /* var ids = [] @@ -381,13 +503,36 @@ export default function extendStruct (Y) { map: {} // overwrite map!! } if (op.requires != null) { - e.requires = op.requires + e.requires = op.require + // TODO: !! + console.warn('requires is used! see same note above for List') } if (op.info != null) { e.info = op.info } return e }, + binaryEncode: function (encoder, op) { + encoder.writeUint8(CMAP) + encoder.writeOpID(op.id) + encoder.writeVarString(op.type) + let info = op.info != null ? JSON.stringify(op.info) : '' + encoder.writeVarString(info) + }, + binaryDecode: function (decoder) { + decoder.skip8() + let op = { + id: decoder.readOpID(), + type: decoder.readVarString(), + struct: 'Map', + map: {} + } + let info = decoder.readVarString() + if (info.length > 0) { + op.info = JSON.parse(info) + } + return op + }, requiredOps: function () { return [] }, diff --git a/test/encode-decode.js b/test/encode-decode.js new file mode 100644 index 00000000..2fe5f21c --- /dev/null +++ b/test/encode-decode.js @@ -0,0 +1,221 @@ +import { test } from 'cutest' +import Chance from 'chance' +import Y from '../src/y.js' +import { BinaryLength, BinaryEncoder, BinaryDecoder } from '../src/Encoding.js' + +function testEncoding (t, write, read, val) { + let binLength = new BinaryLength() + write(binLength, val) + let encoder = new BinaryEncoder(binLength) + write(encoder, val) + let reader = new BinaryDecoder(encoder.dataview) + let result = read(reader) + t.log(`string encode: ${JSON.stringify(val).length} bytes / binary encode: ${encoder.dataview.buffer.byteLength} bytes`) + t.compare(val, result, 'Compare results') +} + +const writeVarUint = (encoder, val) => encoder.writeVarUint(val) +const readVarUint = decoder => decoder.readVarUint() + +test('varUint 1 byte', async function varUint1 (t) { + testEncoding(t, writeVarUint, readVarUint, 42) +}) + +test('varUint 2 bytes', async function varUint2 (t) { + testEncoding(t, writeVarUint, readVarUint, 1 << 9 | 3) +}) +test('varUint 3 bytes', async function varUint3 (t) { + testEncoding(t, writeVarUint, readVarUint, 1 << 17 | 1 << 9 | 3) +}) + +test('varUint 4 bytes', async function varUint4 (t) { + testEncoding(t, writeVarUint, readVarUint, 1 << 25 | 1 << 17 | 1 << 9 | 3) +}) + +test('varUint random', async function varUintRandom (t) { + const chance = new Chance(t.getSeed() * 1000000000) + testEncoding(t, writeVarUint, readVarUint, chance.integer({min: 0, max: (1 << 28) - 1})) +}) + +const writeVarString = (encoder, val) => encoder.writeVarString(val) +const readVarString = decoder => decoder.readVarString() + +test('varString', async function varString (t) { + testEncoding(t, writeVarString, readVarString, 'hello') + testEncoding(t, writeVarString, readVarString, 'test!') + testEncoding(t, writeVarString, readVarString, '☺☺☺') + testEncoding(t, writeVarString, readVarString, '1234') +}) + +test('varString random', async function varStringRandom (t) { + const chance = new Chance(t.getSeed() * 1000000000) + testEncoding(t, writeVarString, readVarString, chance.string()) +}) + +const writeDelete = Y.Struct.Delete.binaryEncode +const readDelete = Y.Struct.Delete.binaryDecode + +test('encode/decode Delete operation', async function binDelete (t) { + let op = { + target: [10, 3000], + length: 40000, + struct: 'Delete' + } + testEncoding(t, writeDelete, readDelete, op) +}) + +const writeInsert = Y.Struct.Insert.binaryEncode +const readInsert = Y.Struct.Insert.binaryDecode + +test('encode/decode Insert operations', async function binInsert (t) { + testEncoding(t, writeInsert, readInsert, { + id: [1, 2], + right: [5, 6], + left: [3, 4], + origin: [7, 8], + parent: [9, 10], + struct: 'Insert', + content: ['a'] + }) + + t.log('left === origin') + testEncoding(t, writeInsert, readInsert, { + id: [1, 2], + right: [5, 6], + left: [3, 4], + origin: [3, 4], + parent: [9, 10], + struct: 'Insert', + content: ['a'] + }) + + t.log('parentsub') + testEncoding(t, writeInsert, readInsert, { + id: [1, 2], + right: [5, 6], + left: [3, 4], + origin: [3, 4], + parent: [9, 10], + parentSub: 'sub', + struct: 'Insert', + content: ['a'] + }) + + t.log('opContent') + testEncoding(t, writeInsert, readInsert, { + id: [1, 2], + right: [5, 6], + left: [3, 4], + origin: [3, 4], + parent: [9, 10], + struct: 'Insert', + opContent: [1000, 10000] + }) + + t.log('mixed content') + testEncoding(t, writeInsert, readInsert, { + id: [1, 2], + right: [5, 6], + left: [3, 4], + origin: [3, 4], + parent: [9, 10], + struct: 'Insert', + content: ['a', 1] + }) + + t.log('origin is null') + testEncoding(t, writeInsert, readInsert, { + id: [1, 2], + right: [5, 6], + left: [3, 4], + origin: null, + parent: [9, 10], + struct: 'Insert', + content: ['a'] + }) + + t.log('left = origin = right = null') + testEncoding(t, writeInsert, readInsert, { + id: [1, 2], + right: null, + left: null, + origin: null, + parent: [9, 10], + struct: 'Insert', + content: ['a'] + }) +}) + +const writeList = Y.Struct.List.binaryEncode +const readList = Y.Struct.List.binaryDecode + +test('encode/decode List operations', async function binList (t) { + testEncoding(t, writeList, readList, { + struct: 'List', + id: [100, 33], + type: 'Array' + }) + + t.log('info is an object') + testEncoding(t, writeList, readList, { + struct: 'List', + id: [100, 33], + type: 'Array', + info: { prop: 'yay' } + }) + + t.log('info is a string') + testEncoding(t, writeList, readList, { + struct: 'List', + id: [100, 33], + type: 'Array', + info: 'hi' + }) + + t.log('info is a number') + testEncoding(t, writeList, readList, { + struct: 'List', + id: [100, 33], + type: 'Array', + info: 400 + }) +}) + +const writeMap = Y.Struct.Map.binaryEncode +const readMap = Y.Struct.Map.binaryDecode + +test('encode/decode Map operations', async function binMap (t) { + testEncoding(t, writeMap, readMap, { + struct: 'Map', + id: [100, 33], + type: 'Map', + map: {} + }) + + t.log('info is an object') + testEncoding(t, writeMap, readMap, { + struct: 'Map', + id: [100, 33], + type: 'Map', + info: { prop: 'yay' }, + map: {} + }) + + t.log('info is a string') + testEncoding(t, writeMap, readMap, { + struct: 'Map', + id: [100, 33], + type: 'Map', + map: {}, + info: 'hi' + }) + + t.log('info is a number') + testEncoding(t, writeMap, readMap, { + struct: 'Map', + id: [100, 33], + type: 'Map', + map: {}, + info: 400 + }) +})